新的ASP.net Identity项目为网站安全带来了一些有用的代码和界面。要使用接口实现自定义系统(而不是使用MVC 5模板中包含的标准Entity Framework实现),需要IPasswordHasher
。
IPasswordHasher
接口namespace Microsoft.AspNet.Identity
{
public interface IPasswordHasher
{
string HashPassword(string password);
PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword);
}
}
是否可以使用密码腌制在ASP.net Identity中通过此接口进行更安全的加密?
答案 0 :(得分:56)
健康警告:了解您正在使用的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都存储为big-endian。)
对于原始版本的ASP.Net Identity ,原始答案仍然有效,如下所示:
@ jd4u是正确的,但是为了得到一些不符合他的回答评论的光线:
Microsoft.AspNet.Identity.PasswordHasher : IPasswordHasher
已经给你盐,
Rfc2898DeriveBytes
生成salt和hash,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);
答案 1 :(得分:34)
“是否可以使用密码腌制来实现更安全的加密 ASP.net身份并通过这个界面?“
是的,该接口是为Core Framework中已存在的PasswordHasher的新实现提供的。
另请注意,默认实现已使用Salt + Bytes。
创建自定义PasswordHasher
(比如MyPasswordHasher
)后,您可以将其分配给UserManager实例,例如userManager.PasswordHasher=new MyPasswordHasher()
See one example of such IPasswordHasher
要使用接口实现自定义系统(而不是使用MVC 5模板中包含的标准Entity Framework实现),需要使用IPasswordHasher。
为了实现EF的备用系统, - 您应实现所有Core接口。 - 不需要IPasswordHasher实现。 PasswordHasher已经在Core框架中提供了它的实现。
答案 2 :(得分:8)
我在从会员资格更新为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实例后,只需设置哈希:
Usermanager.PasswordHasher = new MyPasswordHasher(FormsAuthPasswordFormat.SHA1);
代码抱怨HashPasswordForStoringInConfigFile
方法已被弃用,但这很好,因为我们知道整个练习都是为了摆脱旧技术。