簡體   English   中英

精鹽會帶來安全隱患

[英]Security risks from trimming a salt

因此,我最近為與密碼相關的方法創建了一個靜態類,並且不得不創建一個生成安全鹽的方法。

最初,我實現了RNGCryptoServiceProvider並將n個字節提交到數組中,然后將其轉換為base64並返回了。

問題在於輸出長度,當然經過轉換后比n長( 這很有意義 )。

為了解決這個問題,我將函數更改為下面的方法,我只是想知道通過修剪base64字符串是否會增加安全風險?

/// <summary>
/// Generates a salt for use with the Hash method.
/// </summary>
/// <param name="length">The length of string to generate.</param>
/// <returns>A cryptographically secure random salt.</returns>
public static string GenerateSalt(int length)
{
    // Check the length isn't too short.
    if (length < MIN_LENGTH)
    {
        throw new ArgumentOutOfRangeException("length", "Please increase the salt length to meet the minimum acceptable value of " + MIN_LENGTH + " characters.");
    }

    // Calculate the number of bytes required.
    // https://en.wikipedia.org/wiki/Base64#Padding
    // http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division
    int bytelen = ((3 * length) + 4 - 1) / 4;

    // Create our empty salt array.
    byte[] bytes = new byte[bytelen];

    // Where we'll put our generated salt.
    string salt;

    // Generate a random secure salt.
    using (RNGCryptoServiceProvider randcrypto = new RNGCryptoServiceProvider())
    {
        // Fill our array with random bytes.
        randcrypto.GetBytes(bytes);

        // Get a base64 string from the random byte array.
        salt = GetBase64(bytes);
    }

    // Trim the end off only if we need to.
    if (salt.Length > length)
    {
        // Substring is the fastest method to use.
        salt = salt.Substring(0, length);
    }

    // Return the salt.
    return salt;
}

另外,作為一個附帶問題,我快速瀏覽了一下,但實際上找不到RNGCryptoServiceProviderC#實現的哈希函數實際上是什么。 有人知道嗎?

為什么鹽的長度對您如此重要? 我不認為有任何真正的安全隱患,因為鹽的唯一真正要求是它是隨機且不可猜測的。

換句話說,去吧。

編輯:這是使用Linq的另一種方法。

Random random = new Random();
int length = 25; // Whatever length you want
char[] keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890!£$%^&*()".ToCharArray(); // whatever chars you want
var salt = Enumerable
    .Range(1, length) // equivalent to the loop bit, for(i.. ) 
    .Select(k => keys[random.Next(0, keys.Length - 1)])  // generate a new random char 
    .Aggregate("", (e, c) => e + c); // join them together into a string

這種產生鹽的方式沒有安全風險。

Salt根本不需要那種安全級別,它就在那里,因此彩虹表不能用於破解哈希/加密。 常規的Random類足以創建鹽。

例:

/// <summary>
/// Generates a salt for use with the Hash method.
/// </summary>
/// <param name="length">The length of string to generate.</param>
/// <returns>A random salt.</returns>
public static string GenerateSalt(int length) {
    // Check the length isn't too short.
    if (length < MIN_LENGTH) {
        throw new ArgumentOutOfRangeException("length", "Please increase the salt length to meet the minimum acceptable value of " + MIN_LENGTH + " characters.");
    }

    // Where we'll put our generated salt.
    StringBuilder salt = new StringBuilder(length);

    // Fill our string with random characters.
    Random rnd = new Random();
    string chars = "0123456798ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    for (int i = 0; i < length; i++) {
      salt.Append(chars[rnd.Next(chars.Length)]);
    }

    // Return the salt.
    return salt.ToString();
}

注意:如果函數在關閉時間上使用了不止一次,則您將使用單個Random對象並傳遞到函數中,因為在時間上創建得太近的Random實例將給出相同的隨機序列。

只是為了好玩,這是一種更快的方法(即使代碼看起來不太好)。 嘗試將其剪切並粘貼以查看。 在我的機器上,它的執行時間約為7.1秒,而執行時間約為7.1秒。 由於在每種情況下我都要進行一百萬次迭代,因此我認為執行時間並不那么重要!

string msg = "";
int desiredLength = 93; // Length of salt required
Stopwatch watch = new Stopwatch();
watch.Start();
for (int k=0; k<1000000; k++)
{
    double guidsNeeded = Math.Ceiling(desiredLength / 36.0);
    string salt = "";
    for (int i=0; i<guidsNeeded; i++)
    {
       salt += Guid.NewGuid().ToString();
    }
    salt = salt.Substring(0,desiredLength);
}
msg += watch.ElapsedMilliseconds.ToString(); // 1654 ms

watch.Start();
for (int j=0; j<1000000; j++)
{
    GenerateSalt(93);
}
msg += "\r\n" + watch.ElapsedMilliseconds.ToString(); // 7096 ms

這是將Guffa的代碼用於GenerateSalt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM