【问题标题】:Encrypt File using AES and PyCrypto in Python 3在 Python 3 中使用 AES 和 PyCrypto 加密文件
【发布时间】:2012-06-08 21:32:25
【问题描述】:

我正在使用 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对我来说很新,加密也是。任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: python python-3.x pycrypto


    【解决方案1】:

    正如 PyCrypto API 所说,IV must be a byte string,而不是 text 字符串。

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

    因此代码应该是:

    iv = bytes([ random.randint(0,0xFF) for i in range(16)] )
    

    这样的代码(除了像 Federico 指出的那样不具有密码安全性之外)在 Python 2 中无法正常工作。以下替代方案在这两种情况下都可以正常工作,它是安全的并且它更有效:

    iv = Random.new().read(16)
    

    【讨论】:

    • 没有。 random.randint(0,0xFF) 与许多其他随机数生成器一样,在密码学上并不安全!
    • @Federico 我同意,但我的建议是使用 PyCrypto 的 Random module,而不是 random.randint
    【解决方案2】:

    我想我来得太晚了,但是simple-crypt 提供了一个简单的 pycrypto 包装器,它 (1) 可以解决您的问题,(2) 包括密钥扩展和用于检测修改的 hmac(它使用 AES256 CTR 模式)。

    【讨论】:

      猜你喜欢
      • 2014-01-18
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多