Hmac算法
1. Hmac是Hash-based Messsage Authentication Code的缩写,它是一种基于密钥的消息认证算法
2. 也是一种更安全的额消息摘要算法
例如HmacMD5算法,它相当于我们使用一个随机安全的key,和原始数据混合以后,做MD5摘要
HmacMD5可以看作是带安全Salt的MD5,当我们直接使用MD5的时候,我们需要自己生成一个salt,然后通过salt和
原始数据data,对这两个数据进行MD5摘要,而我们使用HmacMD5的时候,我们直接获取一个HmacMD5的KeyGenerator,
然后通过这个KeyGenerator,获取一个随机的SecretKey,紧接着我们通过Mac.getInstance("HmacMD5")获得一个
Mac的实例,然后我们先初始化这个SecretKey,然后再计算输入数据的MD5
这样我们就可以存储用户密码的MD5改写为直接使用一个secret key直接存储密码的Hmac的MD5
我们使用的Secret Key有64个字节,因此用HmacMD5会更安全
package com.learn.securl;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
public class HmacDemo {
/**
* 我们传入一个hmac算法hmacAlgorithm
* skey以及检索数据的输入
* @param hmacAlgorithm
* @param skey
* @param input
* @return
* @throws Exception
*/
public static byte[] hmac(String hmacAlgorithm, SecretKey skey, byte[] input) throws Exception {
/**
* 然后我们通过一个Mac.getInstance获取一个Mac实例
*/
Mac mac = Mac.getInstance(hmacAlgorithm);
/**
* 我们通过init传入一个SecretKey来初始化
*/
mac.init(skey);
/**
* 紧接着我们用update方法传入原始数据
*/
mac.update(input);
/**
* 通过doFinal方法得到Hmac算法得到的哈希
*/
return mac.doFinal();
}
public static String bytesToHexString(byte... src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
public static void main(String[] args) throws Exception {
// String algorithm = "HmacSHA1";
/**
* 我们只需要把SHA1改成SHA256就行了
* 这个时候生成出来的哈希就是SHA256
*/
String algorithm = "HmacSHA256";
/**
* 原始数据:
*/
String data = "helloworld";
/**
* 随机生成一个Key:
*
* 首先我们通过KeyGenerator.getInstance
* 然后传入算法名称
* 得到一个KeyGenerator
*/
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
/**
* 我们通过generateKey获得一个SecretKey
*/
SecretKey skey = keyGen.generateKey();
/**
* 打印Key:
*
* 然后我们通过getEncoded把SecretKey转换为byte数组
*/
byte[] key = skey.getEncoded();
/**
* 然后打印出来
*/
System.out.println(bytesToHexString(key));
/**
* 用这个Key来计算:
*
* 最后我们可以通过key来计算hmac值
*/
byte[] result = hmac(algorithm, skey, data.getBytes());
/**
* b286b2267357dd475a281bf68d72e88d68586767
* 哈希是20个字节的数组
*/
System.out.println(bytesToHexString(result));
}
}
最后我们总结一下:
1. Hmac就是把Key混入摘要的一种算法
2. 他可以配合MD5,SHA-1等摘要算法
3. 我们需要注意的是,Hmac并不是重新发明的一种摘要算法,而需要配合MD5,SHA-1等摘要算法
4. 最后计算的摘要长度和原摘要算法的长度是相同的