一. HMAC 簡介
通過哈希算法,我們可以驗證一段數據是否有效,方法就是對比該數據的哈希值,例如,判斷用戶口令是否正確,我們用保存在數據庫中的password_md5
對比計算md5(password)
的結果,如果一致,用戶輸入的口令就是正確的。
為了防止黑客通過彩虹表根據哈希值反推原始口令,在計算哈希的時候,不能僅針對原始輸入計算,需要增加一個salt來使得相同的輸入也能得到不同的哈希,這樣,大大增加了黑客破解的難度。
如果salt是我們自己隨機生成的,通常我們計算MD5時采用md5(message + salt)
。但實際上,把salt看做一個“口令”,加salt的哈希就是:計算一段message的哈希時,根據不通口令計算出不同的哈希。要驗證哈希值,必須同時提供正確的口令。
這實際上就是Hmac算法:Keyed-Hashing for Message Authentication。它通過一個標准算法,在計算哈希的過程中,把key混入計算過程中。
和我們自定義的加salt算法不同,Hmac算法針對所有哈希算法都通用,無論是MD5還是SHA-1。采用Hmac替代我們自己的salt算法,可以使程序算法更標准化,也更安全。
使用hmac和普通hash算法非常類似。hmac輸出的長度和原始哈希算法的長度一致。
HMAC算法簡介摘自廖雪峰py教程 原文
二. .NET Core 中的使用
.NET Core 中已經由現成的類,可以直接使用,非常方便。主要有五種類型:HMACMD5、HMACSHA1、HMACSHA256、HMACSHA384、HMACSHA512。其使用方法均為一樣,輸出內容主要有兩種,一種是原始字符串,一種是Base64字符串。
以HMACSHA256為例:
Base64
/// <summary>
/// Base64 SHA256
/// </summary>
/// <param name="data">待加密數據</param>
/// <param name="secret">密鑰</param>
/// <returns></returns>
public static string EncryptWithSHA256(string data, string secret)
{
secret = secret ?? "";
var encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(secret);
byte[] dataBytes = encoding.GetBytes(data);
using (var hmac256 = new HMACSHA256(keyByte))
{
byte[] hashData = hmac256.ComputeHash(dataBytes);
return Convert.ToBase64String(hashData);
}
}
原始字符串:
/// <summary>
/// 原始64位 SHA256
/// </summary>
/// <param name="data">待加密數據</param>
/// <param name="secret">密鑰</param>
/// <returns></returns>
public static string EncryptWithSHA256Original(string data, string secret)
{
secret = secret ?? "";
var encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(secret);
byte[] dataBytes = encoding.GetBytes(data);
using (var hmac256 = new HMACSHA256(keyByte))
{
byte[] hashData = hmac256.ComputeHash(dataBytes);
return BitConverter.ToString(hashData).Replace("-", "").ToLower();
}
}