我有一个场景,用户输入的密码需要存储以备后用。我不能使用散列,因为我需要获取原始密码以供以后使用。
例如,考虑一个电子邮件发件人应用程序,其中用户最初会为他的电子邮件帐户输入密码,应用程序将以加密形式存储它,当应用程序需要发送电子邮件时,它会解密密码并使用它来发送邮件.
现在,这就是我正在做的事情:
- 应用程序在数据库中存储一个主密钥(使用 RNGCryptoServiceProvider 生成)
AES 的密钥和 IV 都是使用 Rfc2898DeriveBytes 从主密钥派生的(对于 Rfc2898DeriveBytes,密码=masterkey 和 salt=user_id)
// the initial, one time masterkey generation, which will be used for all passwords byte[] masterKeyBytes = new byte[32]; new RNGCryptoServiceProvider().GetBytes(masterKeyBytes); // masterkey is saved in database string masterKey = Convert.ToBase64String(masterKeyBytes); // password encryption of a user's password var derivative = new Rfc2898DeriveBytes(masterKey, 128_bit_guid_of_user_id, numberOfIterations) var aes = new AesCryptoServiceProvider(); aes.Key = derivative.GetBytes(32); aes.IV = derivative.GetBytes(16); var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); // get the encrypted password from encryptor ..... .....
我这样做对吗?是否有任何更正?此外,所使用的尺寸(用于密钥大小、masterkeysize 等)是否足够好?
还有几个问题(只是为了了解更多):
从高熵主密钥派生密钥(每个用户的单独 AES 密钥)是否被认为不值得(或更糟)?(即仅使用主密钥作为 AES 密钥就足够了)。如果是这样,为什么?,我的论点是——如果有人为特定用户推断出 AES 密钥,他/她仍然无法推断出主密钥,因此其他用户是安全的。我遇到了 - 在一些智能卡应用程序中使用的“密钥多样化”,它们从每个实例的主密钥派生一个单独的 AES 密钥(这里不适用吗?)
在这种情况下我们可以只使用 PBKDF 来派生密钥,还是应该使用 KBKDF?如果是这样,您能否提及提供 KBKDF 的库(最好来自 .NET 框架)?我知道 RfcDerivativeBytes 使用 PBKDF 派生密钥,但我不知道如何使用 KBKDF 派生密钥。