Asp.Net Core 密码加密方案
使用PBKDF2算法來創建哈希的方法。PBKDF2全稱Password-Based Key Derivation Function,它的基本原理是通過一個偽隨機函數(例如HMAC函數),把明文和一個鹽值作為輸入參數,然后重復進行運算,最終產生秘鑰。如果重復的次數足夠大,破解的成本將非常大。
PBKDF2定義如下
DK = PBKDF2(PRF, Password, Salt, c, dkLen)- PRF 是一個偽隨機函數,可以簡單的理解為 Hash 函數。
- Password 表示口令 。
- Salt 表示鹽值,一個隨機數。
- c 表示迭代次數。
- dkLen 表示最后輸出的密鑰長度。
我們先引入NuGet包
Install-Package Microsoft.AspNetCore.Cryptography.KeyDerivation -Version 3.1.6我們創建一個加密密碼的方法,傳入需要加密密碼,和鹽。參數的含義已經寫在注釋里了。
private static string HashPassword(string value, string salt){var valueBytes = KeyDerivation.Pbkdf2(password: value,//密碼salt: Encoding.UTF8.GetBytes(salt),//鹽prf: KeyDerivationPrf.HMACSHA512,//偽隨機函數,這里是SHA-512iterationCount: 10000,//迭代次數numBytesRequested: 256 / 8);//最后輸出的秘鑰長度return Convert.ToBase64String(valueBytes);}現在密碼有了,還缺點鹽,我們再寫一個隨機鹽生成的方法。
private static string GenerateSalt(){byte[] randomBytes = new byte[128 / 8];using (var generator = RandomNumberGenerator.Create()){generator.GetBytes(randomBytes);return Convert.ToBase64String(randomBytes);}}好了,現在我們有了密碼,有了鹽,也有了加密好的hash值,那么用戶登錄的時候,如何校驗密碼是否正確呢,我們再寫一個hash校驗的方法。這時我們需要輸入用戶輸入的密碼,鹽,以及生成好的hash值,就可以判斷用戶輸入的密碼是否正確了。
private static bool Validate(string password, string salt, string hash)=> HashPassword(password, salt) == hash;至此,內部的密碼加密和校驗部分已經完成了,但還有一個問題,就是創建用戶密碼的時候,如何存儲的用戶密碼的hash值和鹽呢,這里我采取使用“點”進行拼接存儲,即使用salt.hash的形式,相應的,取值校驗,再以“點”進行拆分。具體代碼如下
public static string HashPassword(string password){var salt = GenerateSalt();var hash = HashPassword(password, salt);var result = $"{salt}.{hash}";Console.WriteLine("hash result:{0}", result);return result;}相應的,我們再提供一個對外的密碼校驗函數
public static bool VerifyHashedPassword(string password, string storePassword){if (string.IsNullOrEmpty(password)){throw new ArgumentNullException(nameof(password));}if (string.IsNullOrEmpty(storePassword)){throw new ArgumentNullException(nameof(storePassword));}var parts = storePassword.Split('.');var salt = parts[0];var hash = parts[1];return Validate(password, salt, hash); ;}至此,所有代碼編寫完成,我們下面來試試效果。
我們輸入一個簡單的密碼,1234,循環了5次,模擬5個用戶都使用1234這個密碼,我們看一下效果。
var password = "1234";for (int i = 0; i < 5; i++){var result = PasswordHasher.HashPassword(password);var right = PasswordHasher.VerifyHashedPassword(password, result);Console.WriteLine("password is right:{0}", right);}可以看出這五條數據雖然擁有相同的密碼,但是擁有不同的鹽和hash值。
-
完整的代碼如下
- public class PasswordHasher{private static string HashPassword(string value, string salt){var valueBytes = KeyDerivation.Pbkdf2(password: value,salt: Encoding.UTF8.GetBytes(salt),prf: KeyDerivationPrf.HMACSHA512,iterationCount: 10000,numBytesRequested: 256 / 8);return Convert.ToBase64String(valueBytes);}public static string HashPassword(string password){var salt = GenerateSalt();var hash = HashPassword(password, salt);var result = $"{salt}.{hash}";Console.WriteLine("hash result:{0}", result);return result;}private static bool Validate(string password, string salt, string hash)=> HashPassword(password, salt) == hash;public static bool VerifyHashedPassword(string password, string storePassword){if (string.IsNullOrEmpty(password)){throw new ArgumentNullException(nameof(password));}if (string.IsNullOrEmpty(storePassword)){throw new ArgumentNullException(nameof(storePassword));}var parts = storePassword.Split('.');var salt = parts[0];var hash = parts[1];return Validate(password, salt, hash); ;}private static string GenerateSalt(){byte[] randomBytes = new byte[128 / 8];using (var generator = RandomNumberGenerator.Create()){generator.GetBytes(randomBytes);return Convert.ToBase64String(randomBytes);}}}
總結
以上是生活随笔為你收集整理的Asp.Net Core 密码加密方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# - 习题07_计算1分2分5分硬币
- 下一篇: 文件批量重命名001到100的办法