2017-07-21 98 views
0

我正在致力于将旧网站从经典ASP升级到。其中一部分是将用户(密码以明文形式存储)自动迁移到Identity中。我们正在使用单元测试项目来处理迁移,但该项目无法访问Identity,这是可以理解的。将内部身份验证迁移到ASP.NET Core Identity

这里最好的选择是什么?我看到的主要问题是将密码转换为正确的格式,但我认为我可以查看ASP.NET Identity的源代码并模仿正确迁移迁移中所有内容的功能。有没有更好的办法?

回答

1

ASP.NET身份3使用的散列算法是here。但是,它不是容易在ASP.NET Idetity之外运行,除非您将其依赖项复制到您的项目。

HashPasswordV3

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; 
} 

VerifyHashedPasswordV3

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; 
    } 
} 
0

的密码是纯文本格式,所以你可以简单地从当前数据库加载每个用户和使用标识的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); 

我建议在一个单独的程序作为一个一次性的任务手动运行此。你不会希望这个程序住在新的应用程序中。