我今天刚找到 pycrypto,我一直在研究我的 AES 加密类(class)。不幸的是,它只成功了一半。 self.h.md5 以十六进制格式输出 md5 哈希,并且是 32byte。 这是输出。它似乎解密了消息,但它在解密后放置了随机字符,在这种情况下\n\n\n...我想我的 self.data block 大小有问题,有人知道如何解决这个问题吗?
Jans-MacBook-Pro:test2 jan$ ../../bin/python3 data.py b'RLfGmn5jf5WTJphnmW0hXG7IaIYcCRpjaTTqwXR6yiJCUytnDib+GQYlFORm+jIctest 1 2 3 4 5 endtest\n\n\n\n\n\n\n\n\n\n'
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from os import urandom
class Encryption():
def __init__(self):
self.h = Hash()
def values(self, data, key):
self.data = data
self.key = key
self.mode = AES.MODE_CBC
self.iv = urandom(16)
if not self.key:
self.key = Cfg_Encrypt_Key
self.key = self.h.md5(self.key, True)
def encrypt(self, data, key):
self.values(data, key)
return b64encode(self.iv + AES.new(self.key, self.mode, self.iv).encrypt(self.data))
def decrypt(self, data, key):
self.values(data, key)
self.iv = b64decode(self.data)[:16]
return AES.new(self.key, self.mode, self.iv).decrypt(b64decode(self.data)[16:])
最佳答案
老实说,字符 "\n\n\n\n\n\n\n\n\n\n" 在我看来并不那么随意。 ;-)
您正在 CBC 模式下使用 AES。这要求明文和密文的长度始终是 16 字节的倍数。使用您显示的代码,您实际上应该看到当 data
传递给 encrypt()
不满足此类条件时引发的异常。看起来您添加了足够多的换行符 ('\n' 到任何输入,直到明文恰好对齐。
除此之外,还有两种常见的方法可以解决对齐问题:
从 CBC (
AES.MODE_CBC
) 切换到 CFB (AES.MODE_CFB
)。使用 PyCrypto 默认使用的segment_size
,您将不会对明文和密文长度有任何限制。保留 CBC 并使用类似 PKCS#7 的填充方案,即:
在加密
X
字节的明文之前,在后面追加到达下一个 16 字节边界所需的字节数。所有填充字节都具有相同的值:您要添加的字节数:length = 16 - (len(data) % 16) data += bytes([length])*length
那是 Python 3 风格。在 Python 2 中,您将拥有:
length = 16 - (len(data) % 16) data += chr(length)*length
解密后,从明文后面删除填充指示的字节数:
data = data[:-data[-1]]
尽管我理解您的情况只是类练习,但我想指出,在没有任何形式的身份验证(例如 MAC)的情况下发送数据是不安全的。
关于使用 PyCrypto AES 进行 Python 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14179784/