存储在数据库

时间:2015-06-03 11:16:55

标签: c# sql-server wpf hash securestring

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

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

这是我的背景:

  • 我正在使用WPF客户端应用程序。
  • 我有一个本地SQL数据库(在客户端的计算机上)
  • 密码经过哈希处理并存储在数据库中。
  • 用户尝试登录我的WPF应用程序
  • PasswordBox控件通过SecureString属性将密码存储在SecurePassword中。

现在怎样? 如何散列SecureString而不首先将其强制转换为字符串?

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

我必须接受SecureString在我提到的上下文中无用并使用普通string吗?

1 个答案:

答案 0 :(得分:4)

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

SecureString主要用于将敏感数据存储在内存中。 如果您有服务/网站,则这不如存储在数据库中的值那么重要。这些永远不应该是纯文本,并且您或任何管理员都不能解密 此外,我不确定另一台服务器是否可以解密字符串,因此您在更改服务器或拥有某种群集方案时可能会遇到问题。

特别是对于密码,我更喜欢使用哈希算法(例如SHA256)。 这些不能被加密(就像数字的总和)。 在登录功能的用例中,您将加密用户输入并比较用户和数据库中的哈希值。 (详情见下文) 我还建议在hashinput中添加像userid这样的动态条件,这样两个具有相同密码的用户就会有不同的哈希值。

使用此策略,您不会有使用userpasswords的risc,因此如果数据泄露,此时就不会出现问题。

以下是使用哈希算法

的简短概述

所以(如果给出了securestring)首先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 
  }

存储此hashsum。根据您的编码,它可能会像这样:

  

ac5b208b4d35ec79fa7c14b7a31f9c80392cdab2bc58bc5b79bcfe64b044d899

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

如果客户端使用哈希值,那么它应该是absolut,如果不存在明文(如果文本框不支持securestring则除外)

PS:这只是一个选择。但主要的是从不在任何地方存储明文密码。为了最好,永远不会知道它们,也没有变化让它们解密。

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

根据您的要求和环境,大多数情况下hashsums应该是可接受的解决方案。 (但那不是法律建议,因为我不是律师)