This question already has answers here:
Hashing a SecureString in .NET

(4个答案)


5年前关闭。




我相信我误解了SecureString的基本部分。我知道string是不可变的,并且在堆上找到明文形式的密码或敏感数据。

我正在努力了解的是,如何在需要验证数据库中哈希密码的客户端应用程序中使用SecureString

这是我的上下文:
  • 我正在使用WPF客户端应用程序。
  • 我有一个本地SQL数据库(在客户端计算机上)
  • 密码被散列并存储在数据库中。
  • 用户尝试登录到我的WPF应用程序
  • PasswordBox控件通过SecureString属性将密码存储在SecurePassword中。

  • 怎么办? 如何在不首先将其转换回字符串的情况下对SecureString进行哈希处理?

    到目前为止,我收到的所有建议是编写扩展方法,将SecureString转换为String,对其进行哈希处理,然后将其发送至db进行验证。 但这失败了整个练习!

    我是否必须只接受SecureString在我提到的上下文中是无用的,并使用普通的string

    最佳答案

    SecureString表示为byte [],您可以对字节进行编码,例如使用bitconverter并保存结果。
    此外,SecureString是一种加密,而不是哈希,因为它可以被解密。 (见下文)

    SecureString主要用于将敏感数据存储在内存中。
    如果您有服务/网站,这并不像存储在数据库中的值那么重要。这些绝对不能是纯文本,并且imo 不能由您或任何管理员解密
    另外,我不确定其他服务器是否可以解密字符串,因此当您更改服务器或出现某种群集情况时,您可能会遇到问题。

    特别是对于密码,更喜欢使用哈希算法(例如SHA256)。
    这些不能被解密(像数字的总和)。
    在使用登录功能的情况下,您将加密用户输入并比较用户和数据库中的哈希值。 (下面详细介绍se)
    我还建议向hashinput添加一个动态标准(如userid),以便使用相同密码的2个用户具有不同的哈希值。

    使用此策略,您无需承担用户密码的风险,因此,如果数据泄漏,这时就不成问题了。

    这里是使用哈希算法的简短概述

    所以(如果给出了安全字符串)首先decrypt the SecureString

    String SecureStringToString(SecureString value){
      IntPtr valuePtr = IntPtr.Zero;
      try{
        valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
        return Marshal.PtrToStringUni(valuePtr);
      }
      finally{
        Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
      }
    }
    

    比例如使用SHA256对其进行哈希处理。 From this post
      using (SHA256 hash = SHA256Managed.Create()) {
        Encoding enc = Encoding.UTF8;
    
        //the user id is the salt.
        //So 2 users with same password have different hashes.
        //For example if someone knows his own hash he can't see who has same password
        string input = userInput+userId;
        Byte[] result = hash.ComputeHash(enc.GetBytes(input));
    
        foreach (Byte b in result)
          Sb.Append(b.ToString("x2")); //You could also use other encodingslike BASE64
      }
    

    存储此哈希值。根据您的编码,它可能看起来像这样:



    在您的数据库中。
    如果用户登录,则根据其输入创建哈希并将其与数据库中的哈希进行比较。如果它们相等,则密码正确。
    因此,您无需在任何地方存储纯文本用户密码。

    如果客户端进行哈希处理,则绝对不应以纯文本形式存在(如果文本框不支持安全字符串,则文本框除外)

    PS:这只是一个选择。但是最主要的是永远不要将明文密码存储在任何地方。最好永远不要知道它们,也不要进行任何更改以使它们解密。

    另一种策略是像RSA一样使用非对称加密,但这会变得更加复杂。如果您需要帮助,我会推荐一个专门的帖子。

    根据您的要求和环境,大多数时间哈希值应该是可以接受的解决方案。 (但这不是法律建议,因为我不是律师)

    关于c# - 存储在数据库中的SecureString密码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30618564/

    10-12 17:18