Asp.net 标识密码哈希



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

ASP.net 标识中的IPasswordHasher界面

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

是否可以使用密码加盐在 ASP.net 身份和通过此接口进行更安全的加密?

以下答案的健康警告:了解您正在使用哪个版本的 ASP.Net 标识。如果源代码是 github 存储库中的较新版本之一,则应直接引用源代码。

在我写这篇文章时,密码处理程序的当前版本(3.0.0-rc1/.../PasswordHasher.cs)与下面的答案有很大不同。此较新版本支持多个哈希算法版本,并记录为(在您阅读本文时可能会进一步更改):

版本2:

  • PBKDF2 与 HMAC-SHA1,128 位盐,256 位子项,1000 次迭代。
  • (另请参阅:SDL 加密准则 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 都存储为大端序。
原始

答案对于 ASP.Net 身份的原始版本仍然有效,如下所示:


@jd4u是正确的,但要提供更多的线索,这不适合他的回答的评论:

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

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

PasswordHaser(目前)最终使用的完整代码非常接近:

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

"是否可以使用密码加盐进行更安全的加密 ASP.net 身份和通过这个接口?"

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

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

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

查看此类IPasswordHasher的一个例子

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

要从 EF 实现备用系统,- 您应实现所有核心接口。- 不需要IPasswordHaser实现。PasswordHaser已经在Core框架中提供,因为它的实现。

我在从成员资格更新到 AspNet.Identity 时遇到了一个问题。Rfc2898 哈希与以前使用的哈希不同。这是有充分理由的,但更改哈希将要求所有用户重置其密码。作为解决方案,此自定义实现使其向后兼容:

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

创建用户管理器实例后,只需设置哈希器:

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

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

相关内容

  • 没有找到相关文章

最新更新