在Python 3中使用AES和PyCrypto加密文件

use*_*421 5 python pycrypto python-3.x

我正在使用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必须长度为16个字节.

这是代码:

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))
Run Code Online (Sandbox Code Playgroud)

我尝试过搜索和试验,但似乎无法使其正常工作.Python对我来说很新,加密也是如此.任何帮助将不胜感激.提前致谢.

Squ*_*ree 7

正如PyCrypto API所说,IV 必须是字节字符串,而不是文本字符串.

您的代码片段在Python 2中可以正常工作,因为它们是相同的(也就是说,它们都是类str,除非您处理Unicode文本).在Python 3中,它们是两种完全不同的类型:bytesstr.

因此代码应该是:

iv = bytes([ random.randint(0,0xFF) for i in range(16)] )
Run Code Online (Sandbox Code Playgroud)

这些代码(除了Federico指出的不是加密安全的)在Python 2中也不能正常工作.以下替代方案在两种情况下都可以正常工作,它是安全的并且效率更高:

iv = Random.new().read(16)
Run Code Online (Sandbox Code Playgroud)