2010-08-02 1 views
2

Как только я сгенерировал соль и испортил пароль (используя bcrypt и т. Д.), Было бы лучше сохранить результаты в виде строки или в виде байтового массива в базе данных? Есть ли какие-либо выгоды в любом случае? Или это более субъективное решение?Лучший способ хранения хэшированных паролей и значений солей в базе данных - varchar или двоичный?

+0

I Никогда не видел, чтобы кто-либо использовал НИКАКОГО, кроме стандартной строки varchar. – Layke

ответ

2

VARCHAR должно быть достаточным. На мой взгляд, данные VARCHAR будут легче потреблять и работать с бинарными.

Встроенные поставщики услуг ASP.NET также хранят хэшированные пароли как поля VARCHAR.

2

Если вы используете VARCHAR, убедитесь, что байты являются допустимыми символами или заставляют байты использовать ASCII перед сохранением хеша и соли. Чтобы сделать безопаснее из-за повреждения данных, вы можете либо закодировать байты в Base64, либо в шестнадцатеричном виде, прежде чем хранить их в поле VARCHAR.

Например, если вы храните byte[] выход из MD5 или SHA1 некоторых значений байт может быть удален или заменен, когда byte[] преобразуются в текст, они не действителен 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; 
} 
1

большинство библиотек md5/sha1 возвращают хэши base64 закодирован в этом случае VARCHAR будет достаточно

Смежные вопросы