此类是有时间写的,使用阿里云给出的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 版权协议,转载请附上原文出处链接和本声明。