阿里云实人认证生成签名SignNature工具类

  • Post author:
  • Post category:其他


此类是有时间写的,使用阿里云给出的demo测试正确。实际在调用阿里云的实人认证接口时并未用到,可直接集成相关的sdk。

代码

package cn.com.chnsys.utils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

/**
 * 
 * <p>
 * 类描述 生成阿里云signNature工具类
 * </p>
 *
 * 类说明
 *
 * @author yyb
 * @version 1.0
 */
public class GenerateSignUtil {

	public static String generateSignNature(Map<String, String> map) throws Exception {
		// 1.构建待签名字符串
		// 1.1.按照参数名称的字典顺序对请求中所有的请求参数
		Set<String> keySet = map.keySet();
		List<String> list = new ArrayList<>();
		list.addAll(keySet);
		List<String> sortList = sort(list);
		// 1.2.对排序之后的请求参数的名称和值分别用UTF-8字符集进行URL编码
		// 1.3.将编码后的参数名称和值用英文等号(=)进行连接
		// 1.4. 将等号连接得到的参数组合按步骤1.1排好的顺序依次使用“&”符号连接,即得到规范化请求字符串
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < sortList.size(); i++) {
			String key = sortList.get(i);
			//注:这里应该比较low。在测试过程中发现 冒号:最终会被编码会 “%253A”,是经过了两次。有好的方法请告知
			if (key.equals("Timestamp")) {
				sb.append(AcsURLEncoder.percentEncode(key)).append("=")
						.append(AcsURLEncoder.percentEncode(AcsURLEncoder.percentEncode(map.get(key)))).append("&");
			} else {
				sb.append(AcsURLEncoder.percentEncode(key)).append("=")
						.append(AcsURLEncoder.percentEncode(map.get(key))).append("&");
			}
		}
		String sign = sb.toString();
		String temp = sign.substring(0, sign.length() - 1);
		System.out.println(temp);
		// 1.5.待签名的字符串
		String stringToSign = "GET&" + AcsURLEncoder.percentEncode("/") + "&" + temp.replace("=", "%3D");
		// 2.计算签名
		// 2.1.HMAC值
		byte[] hmacSha1 = HmacSha1(stringToSign, "testsecret&");
		// 2.2.Base64编码
		String result = Base64Encode(hmacSha1);
		// 2.3.返回
		return result;
	}

	private static List<String> sort(List<String> list) {
		if (list != null && list.size() > 0) {
			Collections.sort(list);
		}
		return list;
	}

	/**
	 * 生成hmacsha1签名
	 * 
	 * @param binaryData
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] HmacSha1(byte[] binaryData, String key) throws Exception {
		Mac mac = Mac.getInstance("HmacSHA1");
		SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
		mac.init(secretKey);
		byte[] HmacSha1Digest = mac.doFinal(binaryData);
		return HmacSha1Digest;
	}

	/**
	 * 生成hmacsha1签名
	 * 
	 * @param plainText
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] HmacSha1(String plainText, String key) throws Exception {
		return HmacSha1(plainText.getBytes("UTF-8"), key);
	}

	/**
	 * 生成base64编码
	 * 
	 * @param binaryData
	 * @return
	 */
	public static String Base64Encode(byte[] binaryData) {
		String encodedstr = Base64.getEncoder().encodeToString(binaryData);
		return DatatypeConverter.printBase64Binary(binaryData);
	}

	/**
	 * 测试
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		//阿里云的demo
		String url = "http://ecs.aliyuncs.com/?Timestamp=2016-02-23T12:46:24Z&Format=XML&AccessKeyId=testid&Action=DescribeRegions&SignatureMethod=HMAC-SHA1&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&Version=2014-05-26&SignatureVersion=1.0";
		//阿里云的结果:VyBL52idtt+oImX0NZC+2ngk15Q= 用于对比我们的结果
		Map<String, String> map = new HashMap<>();
		map.put("Timestamp", "2016-02-23T12:46:24Z");
		map.put("Format", "XML");
		map.put("AccessKeyId", "testid");
		map.put("Action", "DescribeRegions");
		map.put("SignatureMethod", "HMAC-SHA1");
		map.put("SignatureNonce", "3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf");
		map.put("Version", "2014-05-26");
		map.put("SignatureVersion", "1.0");
		String result = generateSignNature(map);
		System.out.println(result);
	}
}



版权声明:本文为ChinaMuZhe原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。