消息认证码MAC是在密钥的控制下将任意长的消息映射到一个简短的定长数据分组,并将它附加在消息后。设M是变长的消息,K是仅由收发双方共享的密钥,则M的MAC由如下的函数生成:MAC=CK(M)
发送者每次将MAC附加到消息中。接收者通过重新计算MAC来对消息进行认证。如果接收的MAC与计算出的MAC相同,则
1.消息未被更改过。因为任意更改消息而未更改MAC的行为,都将导致接收的MAC与更改后计算出的MAC不同。而且,对于密钥而言只有收发双方才知 道,其它方无法更改MAC使之与更改后的消息相对应。
2.消息来自其它共享密钥的发送者。因为密钥只有收发双方知道,其它方法无法产生对应的MAC。
MAC函数类似加密函数,但其不需要可逆,而加密函数是需要可逆的,所以MAC函数比加密函数更不容易破解。
上代码:
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* MAC(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容
* 了MD和SHA算法的特性,并在此基础上加入了密钥。因此,我们也常把MAC称为HMAC
* (keyed-Hash Message Authentication Code)。
* <p/>
* Java 6实现
* HmacMD5 128
* HmacSHA1 160
* HmacSHA256 256
* HmacSHA384 384
* HmacSHA512 512
*/
public class MAC {
public static void main(String[] args) throws Exception {
byte[] key=initHmacMD5Key();
System.out.print("密钥为:");
for(byte i:key){
System.out.print(i);
}
System.out.println();
byte[] mac=encodeHmacMD5("hello world".getBytes(),key);
System.out.print("MAC摘要为:");
for(byte i:mac){
System.out.print(i);
}
System.out.println();
}
/**
* 初始化HmacMD5密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacMD5Key() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
// 产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacMD5消息摘要
*
* @param data 待做摘要处理的数据
* @param key 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacMD5(byte[] data, byte[] key)
throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA1密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacSHAKey() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1");
// 产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA1消息摘要
*
* @param data 待做摘要处理的数据
* @param key 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA(byte[] data, byte[] key)
throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA256密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacSHA256Key() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
// 产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA256消息摘要
*
* @param data 待做摘要处理的数据
* @param key 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA256(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA384密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacSHA384Key() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA384");
// 产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA384消息摘要
*
* @param data 待做摘要处理的数据
* @param key 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA384(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
/**
* 初始化HmacSHA512密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initHmacSHA512Key() throws Exception {
// 初始化
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA512");
// 产生密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* HmacSHA512消息摘要
*
* @param data 待做摘要处理的数据
* @param key 密钥
* @return byte[] 消息摘要
* @throws Exception
*/
public static byte[] encodeHmacSHA512(byte[] data, byte[] key) throws Exception {
// 还原密钥
SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512");
// 实例化Mac
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
// 初始化Mac
mac.init(secretKey);
// 执行消息摘要
return mac.doFinal(data);
}
}
以HmacMD5为例结果为: