先使用 NuGet 安裝 Konscious.Security.Cryptography.Argon2 套件,或是使用 .NET CLI 執行以下指令安裝
使用示範:
範例輸出:
參考資料:
Github - kmaragon/Konscious.Security.Cryptography
dotnet add package Konscious.Security.Cryptography.Argon2
使用示範:
static void Main()
{
// 範例密碼
var password = "P@ssw0rd!";
Console.WriteLine($"Password: {password}");
// 雜湊參數
// memoryKb: 使用的記憶體大小(KB) -> 65536 KB = 64 MB
// iterations: 迭代次數
// degreeOfParallelism: 平行度(通常設為 CPU 核心數)
var memoryKb = 65536; // 64 MB
var iterations = 4;
var degreeOfParallelism = Environment.ProcessorCount; // 自動填入 CPU 核心數量
// 產生隨機鹽值(salt)
var salt = GenerateRandomSalt(16);
// 產生雜湊(hash),長度 32 bytes
var hash = HashPassword(password, salt, memoryKb, iterations, degreeOfParallelism, 32);
// 自訂儲存格式:Base64(salt) + '.' + Base64(hash)
var stored = Convert.ToBase64String(salt) + "." + Convert.ToBase64String(hash);
Console.WriteLine($"Stored (salt.hash): {stored}");
// 驗證(正確密碼)
var ok = VerifyPassword(password, stored, memoryKb, iterations, degreeOfParallelism);
Console.WriteLine($"Verification (correct password): {ok}");
// 驗證(錯誤密碼)
var wrong = VerifyPassword("wrong-password", stored, memoryKb, iterations, degreeOfParallelism);
Console.WriteLine($"Verification (wrong password): {wrong}");
}
// 產生隨機鹽值
// 輸入: size = 欲產生的位元組數
// 輸出: 隨機的 byte[] 鹽值
static byte[] GenerateRandomSalt(int size)
{
var salt = new byte[size];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(salt);
return salt;
}
// 使用 Argon2id 雜湊密碼
// 輸入:
// password: 要雜湊的密碼字串
// salt: 已生成的鹽值
// memoryKb: 記憶體大小(KB)
// iterations: 迭代次數
// degreeOfParallelism: 平行度
// hashLength: 要回傳的雜湊長度(bytes)
// 輸出: 雜湊後的 byte[]
static byte[] HashPassword(string password, byte[] salt, int memoryKb, int iterations, int degreeOfParallelism, int hashLength)
{
// 將密碼轉為 UTF-8 bytes
var passwordBytes = Encoding.UTF8.GetBytes(password);
// 建立 Argon2id 實例並設定參數
var argon2 = new Argon2id(passwordBytes)
{
Salt = salt,
DegreeOfParallelism = degreeOfParallelism,
MemorySize = memoryKb,
Iterations = iterations
};
// 取得指定長度的雜湊
return argon2.GetBytes(hashLength);
}
// 驗證密碼是否符合已儲存的 hash
// 輸入:
// password: 要驗證的密碼字串
// stored: 儲存的字串(上方指定格式為 Base64(salt) + '.' + Base64(hash))
// memoryKb, iterations, degreeOfParallelism: 與雜湊相同的參數
// 輸出: bool,若相同則回傳 true
static bool VerifyPassword(string password, string stored, int memoryKb, int iterations, int degreeOfParallelism)
{
// 將儲存字串以 '.' 分割為 salt 與 hash(皆為 Base64)
var parts = stored.Split('.');
if (parts.Length != 2)
return false;
var salt = Convert.FromBase64String(parts[0]);
var expectedHash = Convert.FromBase64String(parts[1]);
// 使用相同參數與 salt 再次雜湊輸入密碼
var actualHash = HashPassword(password, salt, memoryKb, iterations, degreeOfParallelism, expectedHash.Length);
// 使用固定時間比較以避免時序攻擊
return CryptographicOperations.FixedTimeEquals(actualHash, expectedHash);
}
範例輸出:
Argon2id hash demo (Konscious.Security.Cryptography.Argon2)
Password: P@ssw0rd!
Stored (salt.hash): DmlJhletpUOqQGvu2D0Beg==.YV7kqHidt7Nom1q5bo0hxZexrsIZdkuQqwXR2+yBAfk=
參考資料:
Github - kmaragon/Konscious.Security.Cryptography
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com