我有一个WPF应用程序和一个基于MVC的网站。我希望WPF应用程序读取MVC网站为密码信息创建的数据库是特定的哈希密码。如何散列输入的WPF密码以匹配MVC创建的数据库中的散列密码?
我已经拥有的东西:
是使用EF创建的基于MVC的网站 多个数据库。
其中一个数据库包含所有密码信息,例如 哈希密码和盐。
我在MVC项目中使用Simplemembership。
[Table("webpages_Membership")]
public class Membership
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserId { get; set; }
public DateTime? CreateDate { get; set; }
public string ConfirmationToken { get; set; }
public bool IsConfirmed { get; set; }
public DateTime? LastPasswordFailureDate { get; set; }
public int PasswordFailuresSinceLastSuccess { get; set; }
public string Password { get; set; }
public DateTime? PasswordChangedDate { get; set; }
[Required(AllowEmptyStrings = true), MaxLength(128)]
public string PasswordSalt { get; set; }
[MaxLength(128)]
public string PasswordVerificationToken { get; set; }
public DateTime? PasswordVerificationTokenExpirationDate { get; set; }
}
编辑: 我得出结论,我需要在网站上验证密码,并将布尔响应发送回验证凭据的wpf应用程序。我正在进一步研究这个问题,以确定我是否需要wcf或Web服务来实现这一目标。
答案 0 :(得分:3)
我假设您使用的是SimpleMembershipProvider
。默认情况下,密码是经过哈希处理的,这意味着加密只能以“单向”方式进行,一旦对字节数组进行哈希处理,就无法将其转换回纯文本格式。
基本上,您需要做的是从数据库和密码salt中检索哈希密码。然后对您的WPF
应用程序用户提供的密码进行哈希处理(当前使用您刚刚从数据库中检索到的密码盐的纯文本。这是一个示例......
public string HashPassword(string password, string passwordSalt)
{
int saltSize = 128 / 8;//128 bits = 16 bytes
int PBKDF2SubkeyLength = 256 / 8; //256 bits = 32 bytes
byte[] salt;
byte[] subkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, saltSize, 1000))
{
salt = deriveBytes.Salt;
subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
}
byte[] outputBytes = new byte[1 + saltSize + PBKDF2SubkeyLength];
Buffer.BlockCopy(salt, 0, outputBytes, 1, saltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + saltSize, PBKDF2SubkeyLength);
return Convert.ToBase64String(outputBytes);
}
此方法将返回用于验证的密码哈希值,并将用户提供的密码与存储在数据库中的密码哈希值进行比较...
public bool Login(string username, string password)
{
var user = GetUser(username); //get the user from the database including the password hash and salt
//hash the password provided in the login screen
string pwdHash = HashPassword(password, user.PasswordSalt);
return pwdHash.equals(user.PasswordHash);
}
好的,你在这里遇到了一个大问题。从您提供的屏幕截图中我可以看到所有用户的密码盐都是空的,这可能是您所有问题的主要来源,因为密码是经过哈希处理的。我认为导致您发送空白密码盐的原因是您的EF实体中的映射,更具体地说是这一行代码......
[Required(AllowEmptyStrings = true), MaxLength(128)]
public string PasswordSalt { get; set; }
指示EF忽略空密码盐。您需要将其更改为...
[Required, MaxLength(128)]
public string PasswordSalt { get; set; }
但从本质上讲,您确实需要阅读SimpleMembershipProvider
中MVC4
的教程,以便了解如何处理可能出现的其他问题。这是一个很好的Jon Galloway,请阅读
如果您遇到任何问题,请告诉我
答案 1 :(得分:0)
您可以使用客户端应用程序服务来执行此操作;见here