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算法,可以使程序算法更標准化,也更安全。
要計算數據的hamc sha1且base64 encode
python實現
key = "123456789"
data = "abc"
import hmac
import base64
import hashlib
data = hmac.new(key.encode(), data.encode(), digestmod=hashlib.sha1)
print(data)
msg = data.digest()
print(msg)
base64.b64encode(msg)
java實現
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import java.util.Base64;
public class MethodDemo {
public static void main(String[] args) {
var key = "123456789";
var data = "abc";
var s = hamcsha1(data, key);
System.out.println(getBase64String(s));
}
public static String getBase64String(byte[] s) {
return Base64.getEncoder().encodeToString(s);
}
public static byte[] hamcsha1(String data, String key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return mac.doFinal(data.getBytes());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}