package com.xinxin.everyxday.util;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* 签名算法
* 需要用到Base64类,推荐用apache的 commons-codec-1.6.jar,这个是base64标准实现.(没有的话可以问我要)
* 计算结果已经测试过,没问题~ :
* @see
*
*
public static void main(String[] argv){
SignUtil s = new SignUtil();
try {
System.out.println(s.genAuthorizationValue(SignUtil.stringToSign));
} catch (Exception e) {
// TODO:处理异常
e.printStackTrace();
}
}
*
*
*/
public class SignUtil {
/**
* 算法枚举类
* 迁移到项目中时,可以单独作为一个类,而不是作为内部类。
* 作为内部类也无所谓,目前没有hmac的其他算法
* @author hanchao
*
*/
public enum SigningAlgorithm {
HmacSHA1,
HmacSHA256;
}
/*
* StringToSign = HTTP-Verb + "\n" +
Content-Type + "\n" +
Expire + "\n" +
ResourceURI; //资源URI,域名后面所有的部分.
*/
// public static String stringToSign = "GET\n"
// + "application/json\n"
// + "Sat, 20 Nov 2286 17:46:39 GMT\n"
// + "/kills/11923?status=1&page=12";
/**
* 生成请求头中Authorization的ssig部分。(Authorization: accessKey:ssig)
* @param stringToSign 待签名的字符串,拼装结构见上面注释
* @return 截取好的ssig
* @throws Exception 根据情况改成自定义异常
*/
public String genAuthorizationValue(String stringToSign, String secretKey) throws Exception{
try {
String signature = signAndBase64Encode(stringToSign.getBytes("UTF-8"), secretKey, SigningAlgorithm.HmacSHA1);
if(signature.length()>=15)
signature = signature.substring(5,15);
return signature;
} catch (Exception e) {
throw e;
}
}
/**
* 对stringToSign进行加密,返回ssig字符串
* @param data stringToSign.getBytes("UTF-8")
* @param key secretKey
* @param algorithm sha1算法名称
* @return Base64( HMAC-SHA1( 'SecretKey', UTF-8-Encoding-Of( StringToSign ) ) )的结果
* @throws Exception 根据情况改成自定义异常
*/
protected String signAndBase64Encode(byte[] data, String key, SigningAlgorithm algorithm) throws Exception {
try {
byte[] signature = sign(data, key.getBytes("UTF-8"), algorithm);
return new String(Base64.encodeBase64(signature));
} catch (Exception e) {
throw new Exception("Unable to calculate a request signature: " + e.getMessage(), e);
}
}
/**
* hmac-sha1算法
* @param data
* @param key
* @param algorithm
* @return
* @throws Exception 根据情况改成自定义异常
*/
protected byte[] sign(byte[] data, byte[] key, SigningAlgorithm algorithm) throws Exception {
try {
Mac mac = Mac.getInstance(algorithm.toString());
mac.init(new SecretKeySpec(key, algorithm.toString()));
return mac.doFinal(data);
} catch (Exception e) {
throw new Exception("Unable to calculate a request signature: " + e.getMessage(), e);
}
}
}