package com.asiainfo.encryption.s2;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Formatter;

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

import sun.misc.BASE64Encoder;

public class HmacSignature {
	
	private static final String HMAC_SHA1_ALGORITHM = "HMACSHA1"; //算法名称 etc: HMACSHA256、HMACSHA384、HMACSHA512、HMACMD5、(jdk 没有提供HMACSHA224的算法实现)
	                                                              
	private static String toHexString(byte[] bytes) {
		Formatter formatter = new Formatter();
		for (byte b : bytes) {
			formatter.format("%02x", b);
		}
		String hexString = formatter.toString();
		formatter.close();
		return hexString;
	}
	
	public static String calculateRFC2104HMAC(String data, String key) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
		SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
		Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
		mac.init(signingKey);
		return toHexString(mac.doFinal(data.getBytes()));
	}
	
	public static String calculateRFC2104HMAC(String data, byte[] key) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
		SecretKeySpec signingKey = new SecretKeySpec(key, HMAC_SHA1_ALGORITHM);
		Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
		mac.init(signingKey);
		return toHexString(mac.doFinal(data.getBytes()));
	}
	
	public static void main(String[] args) throws Exception {
		KeyGenerator generator = KeyGenerator.getInstance(HMAC_SHA1_ALGORITHM);
		SecretKey key = generator.generateKey();
		byte[] digest = key.getEncoded();
		
		BASE64Encoder encoder = new BASE64Encoder();
		String encoderDigest = encoder.encodeBuffer(digest);
		encoderDigest = encoderDigest.replaceAll("[^(A-Za-z0-9)]", ""); //如果想看到生成的密钥
		System.out.println("Base64编码后的密钥:" + encoderDigest);
		String content = "一代宗师";
		System.out.println("明文: " + content);
		String hmac = calculateRFC2104HMAC(content, encoderDigest);
		System.out.println("密文: " + hmac);
	}
}

Base64编码后的密钥:2KZWSvXuYna5x3YG1F1hH1cM6FPWzPxlesJBnvkdUQpsqoACjDJGWFSJ5jB0uxqaeV49O9fLyiaigscijgA
明文: 一代宗师
密文: a8353af0d3efd2f5dad4e195bbe88325d7201098