手记

java实现HMACSHA256(md5私钥key)加密签名

本文原创作者:一叶飘舟 作者博客地址:http://blog.csdn.net/jdsjlzx

最近在练习一个api时要对参数进行加密,描述如下:

签名机制
每次请求private api 都需要验证签名,发送的参数示例:
$param = array(
amount =1,
price =10000,
type =‘buy’,
nonce =141377098123
key =5zi7w-4mnes-swmc4-egg9b-f2iqw-396z4-g541b
signature =459c69d25c496765191582d9611028b9974830e9dfafd762854669809290ed82
);
nonce 可以理解为一个递增的整数:http://zh.wikipedia.org/wiki/Nonce
key 是申请到的公钥
signature是签名,是将amount price type nonce key等参数通过’&’字符连接起来通过md5(私钥)为key进行sha256算法加密得到的值.

其中关于签名的描述含糊不清,经过一天的摸索,总算搞定了,代码如下。

注意事项:
提交参数的时候一定对参数进行字典进行排序,同样加密参数的时候也要按照字典顺序排序。

public static final String PUBLIC_KEY = "qpda5-eu8uc-bta6c-qrdm4-775v7-nmymb-c1trv";
public static final String PRIVATE_KEY = "*cVd)-6FYvS-97zEU-HT^SJ-9qd6&-Cz*md-;fpGt";

public static void main(String[] args) {
String encryptKey;
try {
encryptKey = MD5Encrypt.getMessageDigest(PRIVATE_KEY);
System.out.println(" encryptKey : " + encryptKey);
String str = sha256_HMAC("key=dhdv5-eu8uc-bta6c-qrdm4-775v7-nmymb-c1trv&nonce=170808230320", encryptKey);
System.out.println(" getSignature : " + str);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

/**
 * 将加密后的字节数组转换成字符串
 * 
 * @param b
 *字节数组
 * @return 字符串
 */
private static String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b != null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1)
hs.append('0');
hs.append(stmp);
}
return hs.toString().toLowerCase();
}

/**
 * sha256_HMAC加密
 * 
 * @param message
 *消息
 * @param secret
 *秘钥
 * @return 加密后字符串
 */
private static String sha256_HMAC(String message, String secret) {
String hash = "";
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
hash = byteArrayToHexString(bytes);
} catch (Exception e) {
System.out.println("Error HmacSHA256 ===========" + e.getMessage());
}
return hash;
}

执行结果如下:

 encryptKey : d9e7fc07ab76555e499f8c650661ed7e
 getSignature : 2601b1fab764e20c135fa0696933fb45705cdd36492421f3af4d2f14c9025463

最后提供MD5Encrypt代码:

public class MD5Encrypt {
private static final String ENCODE = "UTF-8";
private static final String ENCNAME = "MD5";

/**
 * 功能:MD5加密
 * @param strSrc 加密的源字符串
 * @return 加密串 长度32位(hex串)
 * @throws NoSuchAlgorithmException 
 * @throws UnsupportedEncodingException 
 */
public static String getMessageDigest(String strSrc) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md = null;
String strDes = null;

byte[] bt = strSrc.getBytes(ENCODE);
md = MessageDigest.getInstance(ENCNAME);
md.update(bt);
strDes = bytes2Hex(md.digest());
return strDes;
}

/**
 * 将字节数组转为HEX字符串(16进制串)
 * @param bts 要转换的字节数组
 * @return 转换后的HEX串
 */
public static String bytes2Hex(byte[] bts) {
String des = "";
String tmp = null;
for (int i = 0; i < bts.length; i++) {
tmp = (Integer.toHexString(bts[i] & 0xFF));
if (tmp.length() == 1) {
des += "0";
}
des += tmp;
}
return des;
}
}

参考文章:http://30daydo.com/article/181

4人推荐
随时随地看视频
慕课网APP