【问题标题】:Verifying Passwords via Hascode通过 Hascode 验证密码
【发布时间】:2014-07-26 11:37:00
【问题描述】:

经过研究,我发现在登录页面上使用 hascode 验证密码更安全,但谁能告诉我一些代码明智的见解如何实现它?

【问题讨论】:

标签: c# database winforms hash passwords


【解决方案1】:

我不会为你写代码,但我会简要解释一下它是如何工作的。

首先,了解散列和加密之间的区别。如果您没有意识到有区别,请阅读以下内容:Fundamental difference between Hashing and Encryption algorithms

默认情况下,您的密码是纯文本的,这很糟糕。理想情况下,您希望能够以非明文方式存储该密码,以便您可以将其与用户发送给您的数据进行比较。为此,您可以存储加密密码或散列密码。

如果您选择存储加密密码,这意味着您打算在某一天检索原始明文密码(实际上,您永远不需要这样做)。此外,您需要将密钥存储在某处,并且它会变得混乱(因为您也不想存储纯文本,所以您对其进行加密,但随后您需要另一个密钥等),所以让我们假设您不不想走这条路。

如果您选择存储 HASHED 密码,那么您存储的是该密码的固定长度表示。人类无法仅通过查看哈希来确定原始密码(这很好)。

那么,在客户端,您仍然拥有他们需要提交的明文密码。这就是加密的用武之地。您将需要加密客户端和服务器之间的连接。用户提交他们的明文密码,它被加密,这样没人能理解它,你的服务器解密它,然后立即散列它。此时,您现在可以将该哈希值与存储在数据库中的哈希值进行比较。

请注意,对密码客户端进行哈希处理并假设不再需要加密是安全的。

【讨论】:

    【解决方案2】:

    将给定的密码转换为其哈希值:

      using System.Security;
      using System.Security.Cryptography; 
      ...
    
      public static String GetHashValue(String password) {
        // You may find useful to add "salt" here:
        // Byte[] buffer = Encoding.ASCII.GetBytes(password + "some const irregular string");
        Byte[] buffer = Encoding.ASCII.GetBytes(password);
    
        // I've chosen the strongest (but the longest) hash provider
        using (SHA256 provider = SHA256Managed.Create()) {
          return String.Join("", provider.ComputeHash(buffer).Select(x => x.ToString("X2")));
        }
      }
    

    然后尝试通过他/她的登录名和密码哈希找到用户:

      select permissions,
             ... 
        from Users
       where login = @prm_login and
             password_hash = @prm_password_hash  
    

    请注意,您不会在数据库中存储密码(例如“123”),而是哈希(例如@987654325 @)

    【讨论】:

    • SHA* 系列的散列不适用于散列密码,因为它们的速度太快了。您可以使用普通硬件计算大约 1 Giga SHA256 每秒的哈希值。因此,您应该切换到具有 BCrypt 或 PBKDF2 等成本因子的哈希算法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 2015-04-20
    • 1970-01-01
    相关资源
    最近更新 更多