نحوهی محاسبهی هش کلمات عبور کاربران در ASP.NET Identity
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۱۱/۲۸ ۱۴:۱۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
namespace IdentityHash
{
public static class PBKDF2
{
public static byte[] GenerateSalt()
{
using (var randomNumberGenerator = new RNGCryptoServiceProvider())
{
var randomNumber = new byte[32];
randomNumberGenerator.GetBytes(randomNumber);
return randomNumber;
}
}
public static byte[] HashPassword(byte[] toBeHashed, byte[] salt, int numberOfRounds)
{
using (var rfc2898 = new Rfc2898DeriveBytes(toBeHashed, salt, numberOfRounds))
{
return rfc2898.GetBytes(32);
}
}
}
class Program
{
static void Main(string[] args)
{
var passwordToHash = "VeryComplexPassword";
hashPassword(passwordToHash, 50000);
Console.ReadLine();
}
private static void hashPassword(string passwordToHash, int numberOfRounds)
{
var sw = new Stopwatch();
sw.Start();
var hashedPassword = PBKDF2.HashPassword(
Encoding.UTF8.GetBytes(passwordToHash),
PBKDF2.GenerateSalt(),
numberOfRounds);
sw.Stop();
Console.WriteLine();
Console.WriteLine("Password to hash : {0}", passwordToHash);
Console.WriteLine("Hashed Password : {0}", Convert.ToBase64String(hashedPassword));
Console.WriteLine("Iterations <{0}> Elapsed Time : {1}ms", numberOfRounds, sw.ElapsedMilliseconds);
}
}
} /* =======================
* HASHED PASSWORD FORMATS
* =======================
*
* Version 2:
* PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.
* (See also: SDL crypto guidelines v5.1, Part III)
* Format: { 0x00, salt, subkey }
*
* Version 3:
* PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations.
* Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
* (All UInt32s are stored big-endian.)
*/ public static string HashPassword(string password, int numberOfRounds = 1000)
{
if (password == null)
throw new ArgumentNullException("password");
byte[] saltBytes;
byte[] hashedPasswordBytes;
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, numberOfRounds))
{
saltBytes = rfc2898DeriveBytes.Salt;
hashedPasswordBytes = rfc2898DeriveBytes.GetBytes(32);
}
var outArray = new byte[49];
Buffer.BlockCopy(saltBytes, 0, outArray, 1, 16);
Buffer.BlockCopy(hashedPasswordBytes, 0, outArray, 17, 32);
return Convert.ToBase64String(outArray);
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<PasswordHasherOptions>(options => options.IterationCount = 100_000);