【问题标题】:Match hashed password created by Simplemembership with password input from WPF [closed]将 Simplemembership 创建的散列密码与 WPF 输入的密码匹配 [关闭]
【发布时间】:2014-01-08 01:27:18
【问题描述】:

我有一个 WPF 应用程序和一个基于 MVC 的网站。我希望 WPF 应用程序读取 MVC 网站为密码信息创建的数据库,以指定哈希密码。如何对输入的 WPF 密码进行哈希处理以匹配 MVC 创建的数据库中的哈希密码?

我已经拥有的:

  1. 是一个基于 MVC 的网站,使用 EF 创建 多个数据库。

  2. 其中一个数据库包含所有密码信息,例如 哈希密码和盐。

  3. 我在 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 服务来做到这一点。

【问题讨论】:

  • 提供更多信息以便人们提供帮助。密码是如何加密的?实际上是加密的还是散列的?您的网站使用什么加密或散列算法?
  • 我正在使用调用 WebSecurity.CreateUserAndAccount(model.UserName,model.Password); 的帐户控制器中的 webmatrix.webdata;使用 simplemembership,因此密码有自己的数据库链接到用户
  • 在@Leo 提到该信息之前,我对情况知之甚少。
  • 这个问题不再是题外话了,对于遇到此类问题的任何人来说,它都是一个很好的信息来源跨不同的 ASP.NET 版本。让这个问题“离题”只会违背开发者社区。​​span>

标签: c# wpf encryption mvvm passwords


【解决方案1】:

我假设您使用的是SimpleMembershipProvider。默认情况下,密码是散列的,这意味着加密只能“一种方式”完成,一旦一个字节数组被散列,你就不能将它转换回纯文本格式。

所以基本上,您需要做的是从数据库中检索散列密码和密码盐。然后散列您的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; }

但本质上,您确实需要阅读MVC4 中有关SimpleMembershipProvider 的教程,以便您知道如何处理可能出现的其他问题。这是Jon Galloway的一篇好文章,请阅读

如果您遇到任何问题,请告诉我

【讨论】:

  • 我已经实现了这个解决方案,但尚未测试。当我这样做时,我会返回反馈。
  • 哈希密码不匹配 :(。我得到了两个不同的哈希密码
  • 您的 Web 应用程序使用什么版本的 MVC?
  • MVC4 我找到了加密的源代码,我正在使用这一行 Crypto.HashPassword(password); 对我的密码进行哈希处理,出于某种原因,每次使用它时都会给我一个不同的哈希密码
  • 我知道发生了什么...默认情况下,盐作为 string.empty 传递给表以更安全。我可能必须将盐保存在其他地方,然后将其回调以在 wpf 端散列密码
【解决方案2】:

您可以使用客户端应用程序服务来做到这一点;见here

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 2021-08-29
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多