【问题标题】:How to generate an md5 hash with a plaintext string and a known salt [duplicate]如何使用明文字符串和已知盐生成 md5 哈希 [重复]
【发布时间】:2015-08-13 14:56:42
【问题描述】:

我一直在疯狂地试图弄清楚这一点。在 C# 中是否有一种简单的方法来获取像“password123”这样的字符串和盐“vfs5%S]m(_*Y+Tk”并生成单个 MD5 哈希。基本上是网站 http://free-online-web-tools.com/tool/md5 所做的,但使用 C#。

【问题讨论】:

  • 这个问题已经有了答案stackoverflow.com/questions/1300890/…
  • 我不知道你为什么要这样做,但它是过时的密码存储技术。
  • 重复链接没有提供好的答案,MD5 和 SHA-* 适合散列密码,因为它们太快了,因此可能很暴力-太容易强迫了。

标签: c# passwords md5 salt


【解决方案1】:

下面给定的函数为给定的纯文本值生成一个哈希,并返回一个 base64 编码的结果。在计算哈希之前,会生成一个随机盐并将其附加到纯文本中。这个盐存储在哈希值的末尾,因此可以在以后用于哈希验证。

要散列的明文值。该函数不检查该参数是否为空。

哈希算法的名称。允许的值为:“MD5”、“SHA1”、“SHA256”、“SHA384”和“SHA512”(如果指定了任何其他值,将使用 MD5 散列算法)。此值不区分大小写。

在您的情况下,将 hashAlgorithm 设置为“MD5”

盐字节。该参数可以为null,此时会生成一个随机的salt值。

哈希值格式化为 base64 编码的字符串。

public static string ComputeHash(string   plainText,
                                 string   hashAlgorithm,
                                 byte[]   saltBytes)
{
    // If salt is not specified, generate it on the fly.
    if (saltBytes == null)
    {
        // Define min and max salt sizes.
        int minSaltSize = 4;
        int maxSaltSize = 8;

        // Generate a random number for the size of the salt.
        Random  random = new Random();
        int saltSize = random.Next(minSaltSize, maxSaltSize);

        // Allocate a byte array, which will hold the salt.
        saltBytes = new byte[saltSize];

        // Initialize a random number generator.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

        // Fill the salt with cryptographically strong byte values.
        rng.GetNonZeroBytes(saltBytes); 
    }

    // Convert plain text into a byte array.
    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

    // Allocate array, which will hold plain text and salt.
    byte[] plainTextWithSaltBytes = 
            new byte[plainTextBytes.Length + saltBytes.Length];

    // Copy plain text bytes into resulting array.
    for (int i=0; i < plainTextBytes.Length; i++)
        plainTextWithSaltBytes[i] = plainTextBytes[i];

    // Append salt bytes to the resulting array.
    for (int i=0; i < saltBytes.Length; i++)
        plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];

    // Because we support multiple hashing algorithms, we must define
    // hash object as a common (abstract) base class. We will specify the
    // actual hashing algorithm class later during object creation.
    HashAlgorithm hash;

    // Make sure hashing algorithm name is specified.
    if (hashAlgorithm == null)
        hashAlgorithm = "";

    // Initialize appropriate hashing algorithm class.
    switch (hashAlgorithm.ToUpper())
    {
        case "SHA1":
            hash = new SHA1Managed();
            break;

        case "SHA256":
            hash = new SHA256Managed();
            break;

        case "SHA384":
            hash = new SHA384Managed();
            break;

        case "SHA512":
            hash = new SHA512Managed();
            break;

        default:
            hash = new MD5CryptoServiceProvider();
            break;
    }

    // Compute hash value of our plain text with appended salt.
    byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

    // Create array which will hold hash and original salt bytes.
    byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
                                        saltBytes.Length];

    // Copy hash bytes into resulting array.
    for (int i=0; i < hashBytes.Length; i++)
        hashWithSaltBytes[i] = hashBytes[i];

    // Append salt bytes to the result.
    for (int i=0; i < saltBytes.Length; i++)
        hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];

    // Convert result into a base64-encoded string.
    string hashValue = Convert.ToBase64String(hashWithSaltBytes);

    // Return the result.
    return hashValue;
}

更多详情refer here.

【讨论】:

  • 为什么你支持盐的尺寸范围?盐的高熵会增加攻击难度。我想我从未见过可变大小的盐。
  • MD5 或 SHA-* 等快速算法不适用于散列密码,因为它们很容易被暴力破解。相反,应该使用具有 BCrypt 或 PBKDF2 等成本因子的慢散列函数,在这个 answer 中,您可以找到指向 CSharp 示例的链接。
猜你喜欢
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多