Basically, my question is divided into two problems, first of all, I am having this problem when I try running this code [code below] and get an error, like this:
ImportError Traceback (most recent call last) <ipython-input-3-3d0c04910b61> in <module> 1 import hashlib ----> 2 from crypto import Random 3 from crypto.Cipher import AES 4 from base64 import b64encode, b64decode 5 ImportError: cannot import name 'Random' from 'crypto' (C:UsersAhmadanaconda3libsite-packagescrypto__init__.py)
The second problem is when I enter text, i.e: “My data is here” I got the encrypted text as : “GIdd+zxj8m0nMeh7wmZJ+Q==” but reversing the process in decryption it outputs a different text, to validate the process I am using and checking through https://aesencryption.net/ as reference in my work.
My Code:
import hashlib from crypto import Random from crypto.Cipher import AES from base64 import b64encode, b64decode class AESCipher(object): def __init__(self, key): self.block_size = AES.block_size self.key = hashlib.sha256(key.encode()).digest() def encryption(self, plain_text): plain_text = self.__pad(plain_text) iv = Random.new().read(self.block_size) cipher = AES.new(self.key, AES.MODE_CBC, iv) encrypted_text = cipher.encrypt(plain_text.encode()) return b64encode(iv + encrypted_text).decode("utf-8") def decryption(self, encrypted_text): encrypted_text = b64decode(encrypted_text) iv = encrypted_text[:self.block_size] cipher = AES.new(self.key, AES.MODE_CBC, iv) plain_text = cipher.decrypt(encrypted_text[self.block_size:]).decode("utf-8") return self.__unpad(plain_text) def __pad(self, plain_text): number_of_bytes_to_pad = self.block_size - len(plain_text) % self.block_size ascii_string = chr(number_of_bytes_to_pad) padding_str = number_of_bytes_to_pad ** ascii_string padded_plain_text = plain_text + padding_str return padded_plain_text @staticmethod def __unpad(plain_text): last_character = plain_text[len(plain_text) - 2:] return plain_text[:-ord(last_character)]
Advertisement
Answer
In the __pad()
method **
is to be replaced by *
:
padding_str = number_of_bytes_to_pad * ascii_string
In the __unpad()
method the padding size is to be determined from the last byte:
last_character = plain_text[len(plain_text) - 1:]
With these changes the code can be executed successfully with PyCryptodome, see also here for the installation.
Padding does not need to be implemented explicitly. PyCryptodome supports various paddings (including PKCS7) in a dedicated module (Crypto.Util.Padding
).
Please note that deriving the key from a password with a digest is generally insecure. It is more secure to use a reliable key derivation function such as Argon2 or PBKDF2.