AES:如何检测输入的密码错误?

Bas*_*asj 2 python encryption cryptography aes

文本s已被加密:

s2 = iv + Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(pwd).digest(), 
                                    Crypto.Cipher.AES.MODE_CFB, 
                                    iv).encrypt(s.encode())
Run Code Online (Sandbox Code Playgroud)

然后,稍后,用户输入密码pwd2,我们使用以下命令对其进行解密:

iv, cipher = s2[:Crypto.Cipher.AES.block_size], s2[Crypto.Cipher.AES.block_size:]

s3 = Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(pwd2).digest(),
                           Crypto.Cipher.AES.MODE_CFB, 
                           iv).decrypt(cipher)
Run Code Online (Sandbox Code Playgroud)

问题:即使输入的密码pw2错误,最后一行也能正常工作。当然解密后的文本将是随机字符,但不会触发错误。

问:Crypto.Cipher.AES.new(...).decrypt(cipher)密码pw2不正确怎么办?或者至少如何检测错误的密码?


这是一个链接的问题:如果密码无效则使 AES 解密失败,这里讨论了问题的加密部分(较少的编程):AES,这种说“您输入的密码错误”的方法是否安全? .

Luk*_*ark 5

AES 提供机密性,但不提供开箱即用的完整性 - 要获得完整性,您有几个选择。最简单且可以说是最不容易“用脚射击自己”的方法是仅使用 AES-GCM - 请参阅此 Python 示例示例

您也可以使用 HMAC,但这通常需要管理两个不同的密钥,并且有更多的活动部件。如果您可以使用,我会推荐第一个选项。

附带说明,在将用户创建的密码转换为加密密钥时,SHA-256 不是一个很好的 KDF。流行的密码散列算法在这方面做得更好 - 看看 Argon2、bcrypt 或 PBKDF2。

编辑:SHA-256 是一个糟糕的 KDF 的原因与它产生一个糟糕的密码哈希函数的原因是一样的——它太快了。用户创建的 128 位密码通常比 128 位随机序列包含的熵少得多——人们喜欢选择单词、有意义的序列等。用 SHA-256 散列一次并不能真正缓解这个问题。但随着像Argon2一种构造,被散列它设计成缓慢使蛮力攻击远不太可行。