健康警告对于以下答案:了解您正在使用哪个版本的 ASP.Net Identity。如果源代码是 github 存储库中的较新版本之一,您应该直接引用源代码。
当我写这篇文章时,当前版本(3.0.0-rc1/.../PasswordHasher.cs)的密码处理程序与下面的答案有很大不同。这个较新的版本支持多个哈希算法版本,并记录为(并且在您阅读本文时可能会进一步更改):
版本2:
- 具有 HMAC-SHA1 的 PBKDF2、128 位盐、256 位子密钥、1000 次迭代。
- (另请参阅:SDL 加密指南 v5.1,第 III 部分)
- Format:
{ 0x00, salt, subkey }
版本 3:
- 具有 HMAC-SHA256 的 PBKDF2、128 位盐、256 位子密钥、10000 次迭代。
- Format:
{ 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
- (所有 UInt32 均以大端存储。)
原答案仍然有效对于 ASP.Net Identity 的原始版本,如下:
@jd4u 是正确的,但为了提供更多信息,这不适合他的答案的评论:
-
Microsoft.AspNet.Identity.PasswordHasher : IPasswordHasher
already salts for you,
- 更重要的是它使用
Rfc2898DeriveBytes
生成盐和哈希值,
- 它使用行业标准 PBKDF2 (SE讨论在这里, OWASP 此处推荐 PBKDF2).
- 默认Microsoft.AspNet.Identity.UserManager<TUser>实施用途Microsoft.AspNet.Identity.PasswordHasher作为混凝土
IPasswordHasher
-
PasswordHasher
反过来是一个非常简单的包装器(最终)System.Security.Cryptography.Rfc2898DeriveBytes
所以,如果你要使用Rfc2898DeriveBytes
,只需使用PasswordHasher
- 所有繁重的工作都已经为您完成(希望是正确的)。
Details
PasswordHasher(当前)最终使用的完整代码的作用非常接近:
int saltSize = 16;
int bytesRequired = 32;
byte[] array = new byte[1 + saltSize + bytesRequired];
int iterations = SOME; // 1000, afaik, which is the min recommended for Rfc2898DeriveBytes
using (var pbkdf2 = new Rfc2898DeriveBytes(password, saltSize, iterations))
{
byte[] salt = pbkdf2.Salt;
Buffer.BlockCopy(salt, 0, array, 1, saltSize);
byte[] bytes = pbkdf2.GetBytes(bytesRequired);
Buffer.BlockCopy(bytes, 0, array, saltSize+1, bytesRequired);
}
return Convert.ToBase64String(array);