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

最近在练习一个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

你可能感兴趣的:(java)