Theo tài liệu nằm: https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasher.cs
/* =======================
* 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.)
*/
Tại một thời điểm, nhận dạng sử dụng một thuật toán khác nhau băm - có lẽ nó sử dụng định dạng phiên bản 2 trong một, và các định dạng phiên bản 3 trong khác?
Phương thức khởi tạo của lớp có các tùy chọn, bạn có thể thử tinh chỉnh để có được hàm băm đúng không?
public PasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null)
EDIT:
Tôi tìm thấy nguồn v2.0 nhận dạng ở đây: https://aspnetidentity.codeplex.com/ và git repo: https://git01.codeplex.com/aspnetidentity
Nhìn qua nguồn, bạn đi qua phương pháp băm của nó.
Crypto.HashPassword.cs
public static string HashPassword(string password)
{
if (password == null)
{
throw new ArgumentNullException("password");
}
// Produce a version 0 (see comment above) text hash.
byte[] salt;
byte[] subkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
{
salt = deriveBytes.Salt;
subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
}
var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
return Convert.ToBase64String(outputBytes);
}
So với v2 trong bản sắc aspnet lõi:
private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng)
{
const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1; // default for Rfc2898DeriveBytes
const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes
const int Pbkdf2SubkeyLength = 256/8; // 256 bits
const int SaltSize = 128/8; // 128 bits
// Produce a version 2 (see comment above) text hash.
byte[] salt = new byte[SaltSize];
rng.GetBytes(salt);
byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength);
var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
outputBytes[0] = 0x00; // format marker
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength);
return outputBytes;
}
nhận dạng v2 băm và lõi sắc v2 băm dường như khá giống nhau, bây giờ so với bản sắc cốt lõi v3 băm :
private static byte[] HashPasswordV3(string password, RandomNumberGenerator rng, KeyDerivationPrf prf, int iterCount, int saltSize, int numBytesRequested)
{
// Produce a version 3 (see comment above) text hash.
byte[] salt = new byte[saltSize];
rng.GetBytes(salt);
byte[] subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);
var outputBytes = new byte[13 + salt.Length + subkey.Length];
outputBytes[0] = 0x01; // format marker
WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount);
WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize);
Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
return outputBytes;
}
Tôi sẽ không giả vờ hiểu chuyện gì đang diễn ra phương pháp hese, nhưng từ bản sắc v2, và lõi nhận dạng, chúng tôi đã đi từ một constructor parameterless đến một trong đó có trong tùy chọn cấu hình. V2 sử dụng SHA1, V3 sử dụng SHA256 (trong số những thứ khác).
Dường như lõi danh tính theo mặc định sẽ băm bằng cách sử dụng phương thức V3, không tồn tại trong phiên bản cũ hơn - đó sẽ là nguyên nhân gây ra sự cố của bạn.
https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasherOptions.cs
Lưu ý ở trên nguồn, V3 được sử dụng làm mặc định.
/// <summary>
/// Gets or sets the compatibility mode used when hashing passwords.
/// </summary>
/// <value>
/// The compatibility mode used when hashing passwords.
/// </value>
/// <remarks>
/// The default compatibility mode is 'ASP.NET Identity version 3'.
/// </remarks>
public PasswordHasherCompatibilityMode CompatibilityMode { get; set; } = PasswordHasherCompatibilityMode.IdentityV3;
Thật không may, có vẻ như mật khẩu của bạn đã được băm trong lõi danh tính không thể được băm giống nhau trong phiên bản cũ hơn vì phương thức cũ hơn không được triển khai. Có lẽ bạn có thể tạo ra bắt chước của riêng bạn những gì đã được thực hiện trong v3?
Rất tiếc, lớp PasswordHasher dường như chỉ có hàm tạo ít tham số. Nhưng một sự khác biệt phiên bản có thể giải thích nó, ứng dụng Core là trên Identity 3, trong khi ứng dụng ASP.NET 4 là trên Identity 2. Không chắc V3 có sẵn cho .NET 4.6.1 không? –
Tôi hiện đang xem xét việc chuyển thuật toán băm V3 sang ứng dụng ASP.NET 4. Nếu không, tôi đoán các ứng dụng cốt lõi có thể được thay đổi để sử dụng V2 băm thay vì (về cơ bản di chuyển các băm V3 hiện tại để V2 băm), nhưng tôi thực sự muốn ở lại trên V3. Cảm ơn sự giúp đỡ của bạn! –