Closed Daeamon closed 6 years ago
I found a solution. I'm using this code for check if a password hash is being verified by hashing function from SimpleMembershipProvider, and then i reset password by asp.net identity function
Hashing Function
using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Identity;
namespace AspNetCoreSpa.Web.Extensions
{
public class CustomPasswordHasher : PasswordHasher<IdentityUser>
{
public override PasswordVerificationResult VerifyHashedPassword(IdentityUser user, string hashedPassword,
string providedPassword)
{
var isValidPasswordWithLegacyHash = VerifyHashedPassword(hashedPassword, providedPassword);
return isValidPasswordWithLegacyHash
? PasswordVerificationResult.SuccessRehashNeeded
: base.VerifyHashedPassword(user, hashedPassword, providedPassword);
}
private const int _pbkdf2IterCount = 1000;
private const int _pbkdf2SubkeyLength = 256 / 8;
private const int _saltSize = 128 / 8;
public static string HashPassword(string password)
{
byte[] salt;
byte[] buffer2;
if (password == null)
{
throw new ArgumentNullException("password");
}
using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8))
{
salt = bytes.Salt;
buffer2 = bytes.GetBytes(0x20);
}
byte[] dst = new byte[0x31];
Buffer.BlockCopy(salt, 0, dst, 1, 0x10);
Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20);
return Convert.ToBase64String(dst);
}
public static bool VerifyHashedPassword(string hashedPassword, string password)
{
//Checks password using legacy hashing from System.Web.Helpers.Crypto
var hashedPasswordBytes = Convert.FromBase64String(hashedPassword);
if (hashedPasswordBytes.Length != (1 + _saltSize + _pbkdf2SubkeyLength) || hashedPasswordBytes[0] != 0x00)
{
return false;
}
var salt = new byte[_saltSize];
Buffer.BlockCopy(hashedPasswordBytes, 1, salt, 0, _saltSize);
var storedSubkey = new byte[_pbkdf2SubkeyLength];
Buffer.BlockCopy(hashedPasswordBytes, 1 + _saltSize, storedSubkey, 0, _pbkdf2SubkeyLength);
byte[] generatedSubkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, _pbkdf2IterCount))
{
generatedSubkey = deriveBytes.GetBytes(_pbkdf2SubkeyLength);
}
return ByteArraysEqual(storedSubkey, generatedSubkey);
}
internal static string BinaryToHex(byte[] data)
{
var hex = new char[data.Length * 2];
for (var iter = 0; iter < data.Length; iter++)
{
var hexChar = (byte) (data[iter] >> 4);
hex[iter * 2] = (char) (hexChar > 9 ? hexChar + 0x37 : hexChar + 0x30);
hexChar = (byte) (data[iter] & 0xF);
hex[iter * 2 + 1] = (char) (hexChar > 9 ? hexChar + 0x37 : hexChar + 0x30);
}
return new string(hex);
}
[MethodImpl(MethodImplOptions.NoOptimization)]
private static bool ByteArraysEqual(byte[] a, byte[] b)
{
if (ReferenceEquals(a, b))
{
return true;
}
if (a == null || b == null || a.Length != b.Length)
{
return false;
}
var areSame = true;
for (var i = 0; i < a.Length; i++)
{
areSame &= (a[i] == b[i]);
}
return areSame;
}
}
}
AuthorisationController before var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure: true);
var passwordIsOld = CustomPasswordHasher.VerifyHashedPassword(user.PasswordHash,request.Password);
if(passwordIsOld){
var newPassword = CustomPasswordHasher.HashPassword(request.Password);
var ResetToken = await _userManager.GeneratePasswordResetTokenAsync(user);
await _userManager.ResetPasswordAsync(user,ResetToken,request.Password);
}
@Daeamon sounds like you are at the right path. Have you managed to upgrade?
Yes all work properly. But i need a ssr for my application)))
I plan to move the old project from Asp.net MVC to angular +.NET Core))) In old project i used SimpleMembershipProvider. And can i use SimpleMembershipProvider with this project?