繁体   English   中英

是否将散列密码存储为UTF8字符串?

[英]Implications of storing a hashed password as an UTF8 string?

我发现以下代码在将密码存储在MSSQL数据库中之前用于对密码进行哈希处理(该列的类型为NVARCHAR)。

string HashPassword(string password)
{
    var encoding = Encoding.UTF8,
    var plainBytes = encoding.GetBytes(password);
    var hashedBytes = MD5.Create().ComputeHash(plainBytes);
    return encoding.GetString(hashedBytes); //<-- Bad practice?
}

起初,我认为尝试将随机字节存储为UTF8字符串真的很奇怪,我应该将其更改为Base64编码。 但是,除了不良做法之外,以这种方式进行操作是否还有其他实际含义?

并且; 如果有人拥有数据库,这是否意味着不可能使用彩虹表或类似方法尝试粗暴逆转散列,因为原始字节丢失了?

您正在通过减少将被编码的可能字符串的数量来削弱安全性。 每当您的哈希最终成为无效的UTF-8序列时,您最终都会以U + FFFD作为输出字符(Unicode“替换”字符)。 这意味着多个散列以相同的字符串结尾:

using System;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        byte[] hash1 = FillBytes(128);
        byte[] hash2 = FillBytes(129);
        string text1 = Encoding.UTF8.GetString(hash1);
        string text2 = Encoding.UTF8.GetString(hash2);
        Console.WriteLine(text1 == text2);
    }

    static byte[] FillBytes(byte data)
    {
        byte[] bytes = new byte[16];
        for (int i = 0; i < bytes.Length; i++)
        {
            bytes[i] = data;
        }
        return bytes;
    }
}

GetString返回的文本也有可能无法正确存储在SQL Server中,具体取决于您如何配置它。 (如果该字段设置,以便它可以存储在Unicode的东西,这部分是好的。) 如果丢失数据,这甚至更糟- 存储的正确哈希将不匹配计算正确的哈希值,所以有人在打字正确的密码仍将被拒绝访问。 正如我所说,这可能不是问题-但您没有给我们足够的信息来肯定地说,因此至少值得考虑。 如果您使用的都是Base64或hex(都以ASCII数据结尾),那么这部分不会有问题。

首先,使用MD5散列密码是一个坏主意-随着有损文本转换, 进一步削弱它会更糟。 它使攻击者更容易找到仍然以相同文本结尾的错误密码。

我会建议:

  • 您使用更安全的哈希方法(例如bcrypt或PBKDF2)-有关更多详细信息,请参阅Jeff Atwood的博客文章(有关更多内容,请阅读安全性书籍)
  • 要存储散列,请使用Blob(直接存储字节)或转换为base64或hex以保留完整信息。

这可能有效,但是实际上是一个坏习惯。 至少转换将取决于本地字符集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM