Я сейчас экспериментирую со всеми видами шифрования и столкнулся с проблемой, которую не могу понять. Я пытаюсь использовать реализацию AES pycrypto.cipher в режиме cbc с размером блока 256. Все размеры блоков до 128 работают отлично, но выше дает мне следующую ошибку:
32
1536
Traceback (most recent call last):
File "ttt.py", line 38, in <module>
crypter.encryptB64('hallo123', randomstring(size=1024))
File "ttt.py", line 28, in encryptB64
return base64.b64encode(self.encrypt(key.encode(), value)).decode()
File "ttt.py", line 19, in encrypt
crypted = cipher.encrypt(self.pkcs5_pad(value))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pycrypto-2.6.1-py3.6-macosx-10.6-intel.egg/Crypto/Cipher/blocka
lgo.py", line 244, in encrypt
return self._cipher.encrypt(plaintext)
ValueError: Input strings must be a multiple of 16 in length
Первые два числа (32 и 1536) показывают длину ключа (32) и длину дополненного сообщения, которые делятся на 16.
Вот код, который я использую, функция randomstring и библиотека секретов используются только для получения случайных данных, использование данных ручной работы не меняет результат.
import base64
import secrets
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
class AesCrypt256:
BLOCK_SIZE = 256
def pkcs5_pad(self,s):
return s + (self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) * chr(self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE)
def pkcs5_unpad(self,s):
return s[0:-s[-1]]
def encrypt(self, key, value):
iv = Random.new().read(16)
key = hashlib.sha256(key).digest()[:self.BLOCK_SIZE]
cipher = AES.new(key, AES.MODE_CBC, iv)
print(len(key))
print(len(self.pkcs5_pad(value)))
crypted = cipher.encrypt(self.pkcs5_pad(value))
return iv+crypted
def decrypt(self, key, value):
key = hashlib.sha256(key).digest()[:self.BLOCK_SIZE]
iv = value[:16]
crypted = value[16:]
cipher = AES.new(key,AES.MODE_CBC,iv)
return self.pkcs5_unpad(cipher.decrypt(crypted))
def encryptB64(self, key, value):
return base64.b64encode(self.encrypt(key.encode(), value)).decode()
def decryptB64(self, key, value):
return self.decrypt(key.encode(),base64.b64decode(value)).decode()
def randomstring(size=64):
return secrets.token_urlsafe(size)
crypter = AesCrypt256()
crypter.encryptB64('hallo123', randomstring(size=1024))