我正在使用AES算法的c#实现加密文件。我能够使用一对定义良好的IV和Key数组成功地加密和解密文件。
我也用SHA256和MD5算法从密码字符串生成密钥和IV,如下所述:密码作为AES加密/解密的密钥
我的问题是:如果我不知道源文件的内容是什么,那么验证使用的密码是正确的最好方法是什么?
首先,要从密码中导出密钥,应该使用基于密码的密钥派生函数,而不仅仅是MD5。对于。net,你可以使用可怕的Rfc2898DeriveBytes,它实现了PBKDF2 (RFC是基于密码的加密标准,也包含PBKDF1)。要做到这一点,您至少应该存储一个64-128位的随机盐和密文,可能还应该存储一个迭代计数。您可以使用该方法派生密钥和IV(假设您使用随机盐,密钥将始终是不同的)。
现在有两种比较可靠的方法来检测您是否使用了正确的密码(和salt &迭代计数):通过使用认证密码(如AES-GCM)或通过使用PBKDF2派生更多字节。第一个不需要任何额外的存储空间。但是,在知道密码是否正确之前,您必须尝试解密整个文件。如果文件本身被更改,验证也会失败。
或者您可以配置PBKDF2使用SHA-512。然后你可以提取一个256位的AES密钥,一个128位(或者,对于GCM,一个96位)的IV或nonce,以及一个128位的验证值。此验证值可以与密文一起存储。现在您可以检查验证值,从而在解密文件之前验证密码的正确性。一定要向用户表明,对盐、迭代计数、验证值或密文的任何(故意)更改都可能导致密钥或密码被指示为无效。