package com.tu.Security;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;

/**
 * <pre>
 * 消息摘要算法 - MAC
 * 
 * MAC(Message Authentication Code)
 * HMAC(keyed-Hash Message Authentication Code),含有密钥的散列函数算法
 * 任何MD,SHA
 *  -MD系列:HmacMD2 , HmacMD4 , HmacMD5
 *  -SHA系列: HmacSHA1, HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512
 *  
 *  算法:
 *  HmacMD2    实现方:BC
 *  HmacMD4    实现方:BC
 *  HmacMD5    实现方:JDK
 *  HamcSHA1   实现方:JKD
 *  HmacSHA224 实现方:BC
 *  HmacSHA256 实现方:JKD
 *  HmacSHA384 实现方:JKD
 *  HmacSHA512 实现方:JKD
 *  
 *  
 *  
 *  其它消息摘要算法
 *  RipeMD
 *  Tiger
 *  Whirlpool
 *  GOST3411
 *  
 *  Bouncy Castle实现
 * </pre>
 * 
 * @author comtu
 */
public class HMAC {

	public static void main(String[] args) {
		jdkHmacMD5("comtu", "1234567890abcdef");
		bcHmacMD5("comtu", "1234567890abcdef");
	}

	public static void jdkHmacMD5(String msg, String keyParameter) {
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
			SecretKey secretKey = keyGenerator.generateKey();// 产生密钥
			byte[] key = secretKey.getEncoded();// 获取密钥

			key = Hex.decodeHex(keyParameter.toCharArray());//

			// 还原密钥
			SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");
			Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());// 实例化MAC
			mac.init(restoreSecretKey);
			byte[] hmacMD5Bytes = mac.doFinal(msg.getBytes());// 执行摘要
			System.out.println("jdk hmacMD5:" + Hex.encodeHexString(hmacMD5Bytes));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void bcHmacMD5(String msg, String keyParameter) {
		HMac hmac = new HMac(new MD5Digest());

		byte[] b = org.bouncycastle.util.encoders.Hex.decode(keyParameter.getBytes());
		KeyParameter k = new KeyParameter(b);
		hmac.init(k);
		hmac.update(msg.getBytes(), 0, msg.getBytes().length);

		byte[] hmacMD5Bytes = new byte[hmac.getMacSize()];
		hmac.doFinal(hmacMD5Bytes, 0);

		System.out.println("bc hmacMD5:" + org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5Bytes));
	}

}
