因此,我们的目标是使用AES-CBC-256加密文件中的数据。为了导出AES密钥和IV pbkdf2,将使用给定的密码和salt生成384位输出,其中前256位将是密钥,最后128位将是IV。密钥和iv将用于加密文件,然后在加密文件的开头存储密钥的散列,以便在解密发生时,将所提供密钥的散列进行比较,以检查是否提供正确的密码。这是一个安全的方法吗?
发布于 2020-12-22 00:28:42
不,你应该用认证加密或AEAD。
从KDF再生成128位,使用它作为HMAC-SHA-256的密钥,计算IV和密文的HMAC,用密文存储HMAC结果(称为身份验证标记)。
解密时,通过KDF传递密码生成IV和HMAC密钥,计算IV上的HMAC和密文,并与存储的认证标签进行比较。如果它们不匹配,密码就坏了,或者密码被篡改了。不要解密。只有当身份验证标记良好时才解密。
CBC速度慢,因为它必须一次工作一个块,不能并行加密块。CTR会更好。
HMAC是一个强大的MAC,但速度慢。
现代AEAD模式,如AES-GCM,甚至ChaCha20-Poly1305 ( TLS1.3和like中唯一允许的模式,在现代SSH和IPSec中是首选的,ChaPoly是唯一允许的模式,并且是like中的默认模式)比AES-CBC或AES-CBC+HMAC更快。
使用年龄比滚动自己的要好得多。例如,age使用现代的分块AEAD和scrypt,有一个去和锈的实现,并且是由一个有声望的人( go标准库密码的维护者)创建的。
发布于 2020-12-22 02:02:43
您的方法有点类似于openssl用于aes-256-cbc加密的方法,其密钥来自pbkdf2的密码,例如:
openssl aes-256-cbc -e -a -salt -pbkdf2 -iter 10000与您的方法一样,上面的pbkdf2命令中的openssl函数从密码中派生一个348位的密钥,然后将其拆分为一个256位的加密密钥和一个128位的iv。但是,您需要将pbkdf2函数使用的salt存储在某个地方(在上面的openssl命令中,salt以字节8-15的形式存储在密码文本中)。另外,openssl不使用密文存储密钥的散列。但是,解密时不正确的密码/密钥通常会产生填充错误,因此在某些情况下可以用来检测不正确的密码/密钥。
有关如何检测不正确的密码/密钥的详细信息,请参阅https://crypto.stackexchange.com/questions/5921/how-and-why-can-a-decryption-program-tell-me-that-a-key-is-incorrect。
有关openssl aes-256-cbc -e -a -salt -pbkdf2 -iter 10000如何“在引擎盖下”工作的详细信息,请参阅https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption
https://security.stackexchange.com/questions/242417
复制相似问题