2017-07-21 95 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); 

我建議在一個單獨的程序作爲一個一次性的任務手動運行此。你不會希望這個程序住在新的應用程序中。