文本 s
已被加密:
s2 = iv + Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(pwd).digest(),
Crypto.Cipher.AES.MODE_CFB,
iv).encrypt(s.encode())
然后,稍后,用户输入密码 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)
问题:即使输入的密码 pw2
错误,最后一行仍然有效。当然解密的文本会是随机字符,但不会触发错误。
问题:如果密码pw2
不正确,如何使Crypto.Cipher.AES.new(...).decrypt(cipher)
失败?或者至少如何检测错误的密码?
这是一个链接问题:Making AES decryption fail if invalid password 这里是关于问题的加密部分(较少编程)的讨论:AES, is this method to say “The password you entered is wrong” secure? .
最佳答案
AES 提供 secret 性但不提供开箱即用的完整性 - 要获得完整性,您有几种选择。最简单且可以说最不容易“搬起石头砸自己的脚”的方法就是使用 AES-GCM - 请参阅 this Python example或 this one .
您也可以使用 HMAC,但这通常需要管理两个不同的 key 并且有更多的事件部件。如果您可以使用第一个选项,我会推荐它。
旁注,在将用户创建的密码转换为加密 key 时,SHA-256 并不是一个很好的 KDF。流行的密码哈希算法在这方面做得更好——看看 Argon2、bcrypt 或 PBKDF2。
编辑:SHA-256 是一个糟糕的 KDF 的原因与它生成一个糟糕的密码哈希函数的原因相同——只是太快了。例如,用户创建的 128 位密码通常包含的熵远低于 128 位随机序列 - 人们喜欢选择单词、有意义的序列等。使用 SHA-256 散列一次并不能真正缓解这个问题。但是,使用像 Argon2 这样的设计为较慢的构造对其进行哈希处理,使得暴力攻击变得不那么可行。
关于python - AES:如何检测输入了错误的密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59145627/