我正在使用 PyCrypto 在 CBC 模式下使用 AES 加密二进制文件(Python 3.2.3 64 位和 PyCrypto 2.6)。使用以下代码:http://eli.thegreenplace.net/2010/06/25/aes-encryption-of-files-in-python-with-pycrypto/
但遇到以下错误:ValueError: IV must be 16 bytes long.
代码如下:
def encryptFile(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_file:
Input file
out_file:
If None, a StringIO will be returned.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
我尝试过搜索和试验,但似乎无法正常工作。 Python 对我来说很陌生,加密也是如此。任何帮助将不胜感激。提前致谢。
最佳答案
正如 PyCrypto API 所说,IV must be a byte string ,而不是文本字符串。
您的代码片段在 Python 2 中可以正常工作,因为它们是相同的东西(也就是说,它们都是类 str
,除非您处理 Unicode 文本)。在 Python 3 中,它们是两种完全不同的类型:bytes
和 str
。
因此代码应该是:
iv = bytes([ random.randint(0,0xFF) for i in range(16)] )
这样的代码(除了像 Federico 指出的那样不是密码安全的)将不能在 Python 2 中正常工作。以下替代方案在这两种情况下都适用,它安全并且效率更高:
iv = Random.new().read(16)
关于python - 在 Python 3 中使用 AES 和 PyCrypto 加密文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10956274/