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);
}
}
}