Как хешировать пароль
эй, я хотел бы сохранить hash пароля на телефоне, но я не уверен, как это сделать. Я могу только найти методы шифрования. Каков наилучший способ хешировать пароль? благодаря
- Windows Phone 7 и собственный C ++ / CLI
- Как получить версию приложения в Windows Phone?
- Использовать локальные изображения в элементе управления Webbrowser
- Как я могу привязать данные строк к ListBox в WPF / WP7?
- Windows Phone 7 Browser - выключите серое затенение при нажатии ссылок
- Как отправлять данные с помощью HttpClient?
- ASCIIEncoding В Windows Phone 7
- Как увеличить или уменьшить масштаб изображений в WP7?
ОБНОВЛЕНИЕ : ЭТО ОТВЕТ СЕРЬЕЗНО . Вместо этого используйте рекомендации https://stackoverflow.com/a/10402129/251311 .
Вы можете использовать
var md5 = new MD5CryptoServiceProvider(); var md5data = md5.ComputeHash(data);
или
var sha1 = new SHA1CryptoServiceProvider(); var sha1data = sha1.ComputeHash(data);
Чтобы получить data
виде байтового массива, вы можете использовать
var data = Encoding.ASCII.GetBytes(password);
и вернуть строку из md5data
или sha1data
var hashedPassword = ASCIIEncoding.GetString(md5data);
Большинство других ответов здесь несколько устарели от сегодняшних лучших практик. Таким образом, здесь используется приложение PBKDF2 / Rfc2898DeriveBytes для хранения и проверки паролей. Следующий код находится в автономном classе в этом сообщении: Еще один пример того, как хранить hash-листы соленого пароля . Основы очень легкие, поэтому здесь он разбит:
ШАГ 1 Создайте значение соли с криптографическим PRNG:
byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]);
ШАГ 2 Создайте Rfc2898DeriveBytes и получите значение hashа:
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] hash = pbkdf2.GetBytes(20);
ШАГ 3 Объедините байты соли и пароля для последующего использования:
byte[] hashBytes = new byte[36]; Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 20);
ШАГ 4 Поверните объединенную соль + hash в строку для хранения
string savedPasswordHash = Convert.ToBase64String(hashBytes); DBContext.AddUser(new User { ..., Password = savedPasswordHash });
ШАГ 5 Проверьте введенный пользователем пароль на сохраненный пароль
/* Fetch the stored value */ string savedPasswordHash = DBContext.GetUser(u => u.UserName == user).Password; /* Extract the bytes */ byte[] hashBytes = Convert.FromBase64String(savedPasswordHash); /* Get the salt */ byte[] salt = new byte[16]; Array.Copy(hashBytes, 0, salt, 0, 16); /* Compute the hash on the password the user entered */ var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] hash = pbkdf2.GetBytes(20); /* Compare the results */ for (int i=0; i < 20; i++) if (hashBytes[i+16] != hash[i]) throw new UnauthorizedAccessException();
Примечание. В зависимости от требований к производительности вашего конкретного приложения значение «10000» может быть уменьшено. Минимальное значение должно быть около 1000.
Основываясь на замечательном ответе csharptest.net , я написал для этого class:
public sealed class SecurePasswordHasher { /// /// Size of salt /// private const int SaltSize = 16; /// /// Size of hash /// private const int HashSize = 20; /// /// Creates a hash from a password /// /// the password /// number of iterations /// the hash public static string Hash(string password, int iterations) { //create salt byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[SaltSize]); //create hash var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); var hash = pbkdf2.GetBytes(HashSize); //combine salt and hash var hashBytes = new byte[SaltSize + HashSize]; Array.Copy(salt, 0, hashBytes, 0, SaltSize); Array.Copy(hash, 0, hashBytes, SaltSize, HashSize); //convert to base64 var base64Hash = Convert.ToBase64String(hashBytes); //format hash with extra information return string.Format("$MYHASH$V1${0}${1}", iterations, base64Hash); } /// /// Creates a hash from a password with 10000 iterations /// /// the password /// the hash public static string Hash(string password) { return Hash(password, 10000); } /// /// Check if hash is supported /// /// the hash /// is supported? public static bool IsHashSupported(string hashString) { return hashString.Contains("$MYHASH$V1$"); } /// /// verify a password against a hash /// /// the password /// the hash /// could be verified? public static bool Verify(string password, string hashedPassword) { //check hash if (!IsHashSupported(hashedPassword)) { throw new NotSupportedException("The hashtype is not supported"); } //extract iteration and Base64 string var splittedHashString = hashedPassword.Replace("$MYHASH$V1$", "").Split('$'); var iterations = int.Parse(splittedHashString[0]); var base64Hash = splittedHashString[1]; //get hashbytes var hashBytes = Convert.FromBase64String(base64Hash); //get salt var salt = new byte[SaltSize]; Array.Copy(hashBytes, 0, salt, 0, SaltSize); //create hash with given salt var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); byte[] hash = pbkdf2.GetBytes(HashSize); //get result for (var i = 0; i < HashSize; i++) { if (hashBytes[i + SaltSize] != hash[i]) { return false; } } return true; } }
Применение:
//Hash var hash = SecurePasswordHasher.Hash("mypassword"); //Verify var result = SecurePasswordHasher.Verify("mypassword", hash);
Пример hashа может быть следующим:
$MYHASH$V1$10000$Qhxzi6GNu/Lpy3iUqkeqR/J1hh8y/h5KPDjrv89KzfCVrubn
Как вы можете видеть, я также включил итерации в хеш для удобства использования и возможность его обновления, если нам нужно обновить.
Я использую hash и соль для моего шифрования пароля (это тот же хеш, что и членство Asp.Net):
private string PasswordSalt { get { var rng = new RNGCryptoServiceProvider(); var buff = new byte[32]; rng.GetBytes(buff); return Convert.ToBase64String(buff); } } private string EncodePassword(string password, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(password); byte[] src = Encoding.Unicode.GetBytes(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inarray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inarray); }