簡體   English   中英

在數據庫中存儲散列密碼和salt值的最佳方法 - varchar或binary?

[英]Best way to store hashed passwords and salt values in the database - varchar or binary?

一旦我生成了一個鹽並散列密碼(使用bcrypt等),最好將結果存儲為數據庫中的字符串或字節數組? 這兩種方式都有什么好處嗎? 或者這是一個更主觀的決定?

VARCHAR應該足夠了。 在我看來,VARCHAR數據將更容易消費並與二進制文件一起使用。

內置的ASP.NET成員資格提供程序還將散列密碼存儲為VARCHAR字段。

如果使用VARCHAR,請確保字節是有效字符,或者在保存哈希值和salt之前將字節強制為ASCII。 為了使數據損壞更安全,您可能希望在將它們存儲在VARCHAR字段中之前對Base64或Hexadecimal中的字節進行編碼。

例如,如果存儲MD5SHA1byte[]輸出,則當byte[]轉換為text時,某些字節值可能會被刪除或替換,因此它們不是UTF-8 / Unicode。 如果您使用ASCII,這不應該是一個問題,但它仍然可能導致數據損壞。

如果您不想處理Hex,可以使用構建在框架中的這個base64方法Convert.ToBase64String

如果您使用VARBINARY並且不嘗試使用和文本編碼方法,則此問題不應存在,但可能會使哈希比較困難。

...請注意,如果您使用NVARCHAR ,則仍可能發生此數據損壞...

static void Main(string[] args)
{
    var salt = "MySalt";
    var password = "MyPassword";

    var saltedKey = CalculateHash(salt, password);

    Console.WriteLine(saltedKey);
    // MySalt$teGOpFi57nENIRifSW3m1RQndiU=

    var checkHash = CheckHash(saltedKey, password);
    Console.WriteLine(checkHash);
    // True
}

private static string CalculateHash(string saltOrSaltedKey, string password)
{
    var salt =
        saltOrSaltedKey.Contains('$')
        ? saltOrSaltedKey.Substring(0, saltOrSaltedKey.IndexOf('$') + 1)
        : saltOrSaltedKey + '$';

    var newKey = Encoding.UTF8.GetBytes(salt + password);

    var sha1 = SHA1.Create();
    sha1.Initialize();
    var result = sha1.ComputeHash(newKey);

    // if you replace this base64 version with one of the encoding 
    //   classes this will become corrupt due to nulls and other 
    //   control character values in the byte[]
    var outval = salt + Convert.ToBase64String(result);

    return outval;
}

private static bool CheckHash(string saltedKey, string password)
{
    var outval = CalculateHash(saltedKey, password);
    return outval == saltedKey;
}

大多數md5 / sha1庫返回哈希base64編碼,在這種情況下varchar就足夠了

暫無
暫無

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

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