如何检查Python的AES解密错误?

时间:2015-08-19 09:47:19

标签: python aes pycrypto

我使用python加密和解密文件。文件加密后,尝试解密如下:

from Crypto.Cipher import AES
from Crypto import Random
def decrypt(in_file, out_file, pwd, key_len=32):
    bs = AES.block_size
    salt = in_file.read(bs)[len('Salted__'):]
    key, iv = derive_keyiv(pwd, salt, key_len, bs)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    next_chunk = ''
    finished = False
    try:
        while not finished:
            chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024*bs))
            if len(next_chunk) == 0:
                padding_len = ord(chunk[-1])
                chunk = chunk[:-padding_len]
                finished = True
            out_file.write(chunk)
        return True, None
    except Exception as e:
        return False, e

但是如果密码输入错误,decrypt仍然会解密in_file并写入out_file并且没有异常抛出。

如何在解密期间检查密码错误?

1 个答案:

答案 0 :(得分:2)

AES本身无法检查密钥是否正确"。它只是一个纯函数,可以将某些字节转换为其他字节。

要实现您的目标,您需要自己实现。一种方法是在加密之前向明文添加一个固定的标题(如16字节的零)。在解密时,如果匹配则检查并丢弃所述标头,或者如果标头不匹配则引发错误。

附注:您在没有任何身份验证的情况下进行加密,这可能是不安全的。

修改

首先,您应该添加身份验证。没有身份验证的加密很容易导致许多安全漏洞,许多安全漏洞对于未经训练的人来说并不明显。特别是因为您在CBC模式下使用AES,您可以打开自己填充oracle攻击而无需身份验证。

当您以正确的方式进行经过身份验证的加密(encrypt-then-mac)时,如果用户输入了错误的密码,您将收到身份验证错误。如果你想进一步区分错误的密码和篡改的数据,你必须设计自己的方法,比如在前面加上幻数的密文。