一直以为HMAC_SHA1和SHA1没有任何区别,直到现在才发现它俩不是完全一样的。
HMAC的百度百科解释:
“HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。”
可以看出,HMAC是需要一个密钥的。所以,HMAC_SHA1也是需要一个密钥的,而SHA1不需要。
以下是两种算法在java中的实现:
如下方法是使用sha1计算一个文件的摘要,不需要密钥,有点类似于md5,注意这句:
MessageDigest.getInstance("SHA-1"); //传的是SHA-1
public static String sha1Digest(String filename) {
InputStream fis = null;
byte[] buffer = new byte[Constants.BUFFER_SIZE];
int numRead = 0;
MessageDigest sha1;
try {
fis = new FileInputStream(filename);
sha1 = MessageDigest.getInstance("SHA-1");
while ((numRead = fis.read(buffer)) > 0) {
sha1.update(buffer, 0, numRead);
}
return toHexString(sha1.digest());
} catch (Exception e) {
System.out.println("error");
return null;
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
如下方法是使用hmacsha1计算字符串的签名,需要一个密钥,一般用来作服务器端的签名验证。
Constants.APP_SECRET
注意这句:
Mac.getInstance("HmacSHA1");//传的是HmacSHA1
private static byte[] getHmacSHA1(String src)
throws NoSuchAlgorithmException, UnsupportedEncodingException,
InvalidKeyException {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secret = new SecretKeySpec(
Constants.APP_SECRET.getBytes("UTF-8"), mac.getAlgorithm());
mac.init(secret);
return mac.doFinal(src.getBytes());
}