如何检查Python';s AES解密错误?

如何检查Python';s AES解密错误?,python,aes,pycrypto,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,

我正在使用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
但是如果密码输入错误,
解密
仍会对
in_文件
进行解密,并写入
out_文件
,并且不会引发异常

如何在解密过程中检查密码错误?

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

要实现你想要的,你需要自己去实现。一种方法是在加密之前向明文中添加一个固定的头(比如16字节的零)。解密后,如果所述报头匹配,则检查并丢弃该报头;如果报头不匹配,则引发错误

旁注:您在进行加密时没有任何身份验证,这可能是不安全的

编辑 首先,您应该添加身份验证。没有身份验证的加密很容易导致许多安全缺陷,其中许多对于未经培训的人来说并不明显。特别是由于您在CBC模式下使用AES,您可能会在不进行身份验证的情况下对oracle攻击进行填充


当您以正确的方式进行身份验证加密(加密然后mac)时,如果用户输入错误的密码,您将收到身份验证错误。如果你想进一步区分错误的密码和篡改的数据,你必须设计自己的方法,比如预写一个魔法数字的密文。

如果你能真正验证填充,为什么还要添加额外的零块?你说对了。身份验证是加密然后MAC的方法。@ArtjomB。身份验证无法区分被篡改的文件和不正确的密码。@ArtjomB。仔细想想,在验证mac之后验证填充确实是一种方法。但如果模式是GCM,例如,身份验证无法区分不正确的密码和被篡改的数据。是的,身份验证与仅检测密码中的键入略有不同,但我认为,如果文件被篡改,您不想尝试打开它。“就像预加一个魔法数字的密文。”该数字的长度决定了正确检测错误密码的概率。如果它的长度为4字节,那么$2^{-4*8}$就有可能检测不到已经很低的错误密码。