2

I am trying to implement aes encryption and decryption in python. When I execute code, it returns error. I have installed anaconda on my machine. I am running scripts in jupyter notebook.

!pip install pycryptodome

import base64
from Crypto import Random
from Crypto.Cipher import AES

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]

class AESCipher:

    def __init__( self, key ):
        self.key = key

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

    def decrypt( self, enc ):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] ))

cipher = AESCipher('mysecretpassword')
encrypted = cipher.encrypt('Secret')
decrypted = cipher.decrypt(encrypted)
print(encrypted)
print(decrypted)

How to solve this ?

4
  • 1
    please fix your indentation. what is the error? (which line, etc...) Commented Sep 4, 2018 at 12:58
  • raw=pad(raw). TypeError: Object type <class 'str'> cannot be passed to C code Commented Sep 4, 2018 at 13:09
  • Your code is written for Python2, in Python3 str and bytes are differend objects. You'll have to replace all your strings with bytes (see str.encode). Commented Sep 4, 2018 at 19:08
  • I made the following changes to the above code. pwd=b"mysecretpassword" cipher = AESCipher(pwd) msg=b"Secret" encrypted = cipher.encrypt(msg) print(encrypted) print(decrypted) It returns TypeError: can't concat str to bytes Commented Sep 5, 2018 at 4:47

2 Answers 2

3

just update unpad to be unpad = lambda s : s[0:-ord(s[-1:])] the main issue that ord() expects string of length one if you try to print value of s[-1] it prints 10 which not one char but s[-1:] printed value is b'\n' which is one char

also encode key to be bytes bytes(key, 'utf-8') and pad

pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')

to make sure all inputs are bytes

from hashlib import sha256
import base64
from Crypto import Random
from Crypto.Cipher import AES

BS = 16
pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
unpad = lambda s : s[0:-ord(s[-1:])]

class AESCipher:

    def __init__( self, key ):
        self.key = bytes(key, 'utf-8')

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

    def decrypt( self, enc ):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] )).decode('utf8')

cipher = AESCipher('mysecretpassword')
encrypted = cipher.encrypt('Secret')
decrypted = cipher.decrypt(encrypted)

print(encrypted)
print(decrypted)
Sign up to request clarification or add additional context in comments.

4 Comments

It again returns the same error. TypeError: Object type <class 'str'> cannot be passed to C code
@Jozf I have updated my answer I think it is working fine now I tried it on jjupyter notebook
Thank you. But in the output, there is b before encrypted and decrypted data. Did you see that ? b'6tx+0XpByP2w2cluCcDgYLnx3Zu65vbM8+Db2su4yKg=' b'Secret' How can we remove that ?
@Jozf just decode the result .decode('utf8') I updated it in answer
1

//First pip install pycryptodome -- (pycrypto is obsolete and gives issues) // pip install pkcs7

from Crypto import Random
from Crypto.Cipher import AES
import base64
from pkcs7 import PKCS7Encoder
from app_settings.views import retrieve_settings # my custom settings

app_secrets = retrieve_settings(file_name='secrets');


def encrypt_data(text_data):
                    #limit to 16 bytes because my encryption key was too long
                    #yours could just be 'abcdefghwhatever' 
    encryption_key = app_secrets['ENCRYPTION_KEY'][:16]; 

    #convert to bytes. same as bytes(encryption_key, 'utf-8')
    encryption_key = str.encode(encryption_key); 
    
    #pad
    encoder = PKCS7Encoder();
    raw = encoder.encode(text_data) # Padding
    iv = Random.new().read(AES.block_size ) #AES.block_size defaults to 16

                                 # no need to set segment_size=BLAH
    cipher = AES.new( encryption_key, AES.MODE_CBC, iv ) 
    encrypted_text = base64.b64encode( iv + cipher.encrypt( str.encode(raw) ) ) 
    return encrypted_text;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.