Asp.net身份密码哈希

新的ASP.net Identity项目为网站安全带来了一些有用的代码和界面。 要使用接口实现自定义系统(而不是使用包含在MVC 5模板中的标准entity framework实现),需要IPasswordHasher

IPasswordHasher身份的IPasswordHasher接口

 namespace Microsoft.AspNet.Identity { public interface IPasswordHasher { string HashPassword(string password); PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword); } } 

是否有可能使用密码salting更安全的encryption在ASP.net身份和通过这个接口?

“是否有可能使用密码salting在ASP.net身份和通过这个接口更安全的encryption?”

是的,这个接口是为在核心框架中已经存在的PasswordHasher的新实现提供的。

另外请注意,默认实现已经在使用Salt + Bytes。

创build自定义PasswordHasher (比如说MyPasswordHasher )后,可以将其分配给UserManager实例,如userManager.PasswordHasher=new MyPasswordHasher()

看到这样的IPasswordHasher的一个例子

要使用接口实现自定义系统(而不是使用包含在MVC 5模板中的标准entity framework实现),需要IPasswordHasher。

为了从EF实现备用系统,你必须实现所有的Core接口。 – IPasswordHasher实现不是必需的。 在实施中,PasswordHasher已经在Core框架中提供。

以下答案的健康警告 :知道您使用的是哪个版本的ASP.Net身份。 你应该直接引用源代码,如果它是来自github存储库的新版本之一。

当我写这个时,密码处理程序的当前版本( 3.0.0-rc1 /…/ PasswordHasher.cs )与下面的答案有很大的不同。 这个更新的版本支持多个散列algorithm版本,并logging为(并且可能会在您阅读本文时进一步更改):

版本2:

  • PBKDF2与HMAC-SHA1,128位盐,256位子密钥,1000次迭代。
  • (另请参阅:SDLencryption指南v5.1,第III部分)
  • 格式: { 0x00, salt, subkey }

版本3:

  • PBKDF2与HMAC-SHA256,128位盐,256位子密钥,10000次迭代。
  • 格式: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
  • (所有UInt32都存储为big-endian。)

原始答案仍然适用于原始版本的ASP.Net Identity ,如下所示:


@ jd4u是正确的,但要摆脱一点点不适合他的回答评论:

  • Microsoft.AspNet.Identity.PasswordHasher : IPasswordHasher已经为你服务,
    • 更重要的是它使用Rfc2898DeriveBytes来生成salt和hash,
    • 它使用行业标准PBKDF2( SE讨论在这里 ,OWASP 推荐PBKDF2在这里 )。
  • 默认的Microsoft.AspNet.Identity.UserManager<TUser>实现使用Microsoft.AspNet.Identity.PasswordHasher作为具体的IPasswordHasher
  • PasswordHasher反过来是一个非常简单的包装(最终) System.Security.Cryptography.Rfc2898DeriveBytes

所以,如果你打算使用Rfc2898DeriveBytes ,只需使用PasswordHasher – 所有繁重的工作已经完成(希望是正确的)。

细节

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); 

从Membership到AspNet.Identity更新时,遇到了一个问题。 Rfc2898哈希与以前使用的哈希不同。 这是有原因的,但改变哈希将需要所有的用户重置他们的密码。 作为一个解决scheme,这个自定义实现使其向后兼容:

 public class MyPasswordHasher : PasswordHasher { public FormsAuthPasswordFormat FormsAuthPasswordFormat { get; set; } public MyPasswordHasher(FormsAuthPasswordFormat format) { FormsAuthPasswordFormat = format; } public override string HashPassword(string password) { return FormsAuthentication.HashPasswordForStoringInConfigFile(password, FormsAuthPasswordFormat.ToString()); } public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { var testHash = FormsAuthentication.HashPasswordForStoringInConfigFile(providedPassword, FormsAuthPasswordFormat.ToString()); return hashedPassword.Equals(testHash) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed; } } 

一旦你创build你的UserManager实例,只需设置散列器:

 Usermanager.PasswordHasher = new MyPasswordHasher(FormsAuthPasswordFormat.SHA1); 

该代码抱怨HashPasswordForStoringInConfigFile方法已被弃用,但这很好,因为我们知道整个练习是摆脱旧技术。