我正在致力于将旧网站从经典ASP升级到很。其中一部分是将用户(密码以明文形式存储)自动迁移到Identity中。我们正在使用单元测试项目来处理迁移,但该项目无法访问Identity,这是可以理解的。将内部身份验证迁移到ASP.NET Core Identity
这里最好的选择是什么?我看到的主要问题是将密码转换为正确的格式,但我认为我可以查看ASP.NET Identity的源代码并模仿正确迁移迁移中所有内容的功能。有没有更好的办法?
我正在致力于将旧网站从经典ASP升级到很。其中一部分是将用户(密码以明文形式存储)自动迁移到Identity中。我们正在使用单元测试项目来处理迁移,但该项目无法访问Identity,这是可以理解的。将内部身份验证迁移到ASP.NET Core Identity
这里最好的选择是什么?我看到的主要问题是将密码转换为正确的格式,但我认为我可以查看ASP.NET Identity的源代码并模仿正确迁移迁移中所有内容的功能。有没有更好的办法?
ASP.NET身份3使用的散列算法是here。但是,它不是容易在ASP.NET Idetity之外运行,除非您将其依赖项复制到您的项目。
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;
}
private static bool VerifyHashedPasswordV3(byte[] hashedPassword, string password, out int iterCount)
{
iterCount = default(int);
try
{
// Read header information
KeyDerivationPrf prf = (KeyDerivationPrf)ReadNetworkByteOrder(hashedPassword, 1);
iterCount = (int)ReadNetworkByteOrder(hashedPassword, 5);
int saltLength = (int)ReadNetworkByteOrder(hashedPassword, 9);
// Read the salt: must be >= 128 bits
if (saltLength < 128/8)
{
return false;
}
byte[] salt = new byte[saltLength];
Buffer.BlockCopy(hashedPassword, 13, salt, 0, salt.Length);
// Read the subkey (the rest of the payload): must be >= 128 bits
int subkeyLength = hashedPassword.Length - 13 - salt.Length;
if (subkeyLength < 128/8)
{
return false;
}
byte[] expectedSubkey = new byte[subkeyLength];
Buffer.BlockCopy(hashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length);
// Hash the incoming password and verify it
byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength);
return ByteArraysEqual(actualSubkey, expectedSubkey);
}
catch
{
// This should never occur except in the case of a malformed payload, where
// we might go off the end of the array. Regardless, a malformed payload
// implies verification failed.
return false;
}
}
的密码是纯文本格式,所以你可以简单地从当前数据库加载每个用户和使用标识的UserManager
类将它们添加到新的数据库。
UserManager
类有一个CreateAsync
方法需要一个密码,它会处理你的哈希。
实施例:
var user = new IdentityUser // or whatever your user class is
{
UserName = userName,
Email = email,
// set other required properties
};
var result = await userManager.CreateAsync(user, password);
我建议在一个单独的程序作为一个一次性的任务手动运行此。你不会希望这个程序住在新的应用程序中。