Java签名算法参考
签名代码:UrlUtil.java
import java.net.URLEncoder; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; public class UrlUtil { private static Logger logger = Logger.getLogger(UrlUtil.class); private final static String CHARSET_UTF8 = "utf8"; /** * * @param url * @return */ public static String urlEncode(String url) { if (!StringUtils.isEmpty(url)) { try { url = URLEncoder.encode(url, "UTF-8"); } catch (Exception e) { logger.warn("Url encode error:" + e.getMessage()); } } return url; } public static String generateQueryString(Mapparams, boolean isEncodeKV) { StringBuilder canonicalizedQueryString = new StringBuilder(); for (Map.Entry entry : params.entrySet()) { if (isEncodeKV) canonicalizedQueryString.append(percentEncode(entry.getKey())).append("=") .append(percentEncode(entry.getValue())).append("&"); else canonicalizedQueryString.append(entry.getKey()).append("=") .append(entry.getValue()).append("&"); } if (canonicalizedQueryString.length() > 1) { canonicalizedQueryString.setLength(canonicalizedQueryString.length() - 1); } return canonicalizedQueryString.toString(); } public static String percentEncode(String value) { try { // 使用URLEncoder.encode编码后,将"+","*","%7E"做替换即满足 API规定的编码规范 return value == null ? null : URLEncoder.encode(value, CHARSET_UTF8) .replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); } catch (Exception e) { //不可能发生的异常 } return ""; } }
SignatureUtils.java
import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Map; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; public class SignatureUtils { private final static String CHARSET_UTF8 = "utf8"; private final static String ALGORITHM = "UTF-8"; private final static String SEPARATOR = "&"; public static MapsplitQueryString(String url) throws URISyntaxException, UnsupportedEncodingException { URI uri = new URI(url); String query = uri.getQuery(); final String[] pairs = query.split("&"); TreeMap queryMap = new TreeMap (); for (String pair : pairs) { final int idx = pair.indexOf("="); final String key = idx > 0 ? pair.substring(0, idx) : pair; if (!queryMap.containsKey(key)) { queryMap.put(key, URLDecoder.decode(pair.substring(idx + 1), CHARSET_UTF8)); } } return queryMap; } public static String generate(String method, Map parameter, String accessKeySecret) throws Exception { String signString = generateSignString(method, parameter); System.out.println("signString---"+signString); byte[] signBytes = hmacSHA1Signature(accessKeySecret + "&", signString); String signature = newStringByBase64(signBytes); System.out.println("signature---"+signature); if ("POST".equals(method)) return signature; return URLEncoder.encode(signature, "UTF-8"); } public static String generateSignString(String httpMethod, Map parameter) throws IOException { TreeMap sortParameter = new TreeMap (); sortParameter.putAll(parameter); String canonicalizedQueryString = UrlUtil.generateQueryString(sortParameter, true); if (null == httpMethod) { throw new RuntimeException("httpMethod can not be empty"); } StringBuilder stringToSign = new StringBuilder(); stringToSign.append(httpMethod).append(SEPARATOR); stringToSign.append(percentEncode("/")).append(SEPARATOR); stringToSign.append(percentEncode(canonicalizedQueryString)); return stringToSign.toString(); } public static String percentEncode(String value) { try { return value == null ? null : URLEncoder.encode(value, CHARSET_UTF8) .replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); } catch (Exception e) { } return ""; } public static byte[] hmacSHA1Signature(String secret, String baseString) throws Exception { if (StringUtils.isEmpty(secret)) { throw new IOException("secret can not be empty"); } if (StringUtils.isEmpty(baseString)) { return null; } Mac mac = Mac.getInstance("HmacSHA1"); SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), ALGORITHM); mac.init(keySpec); return mac.doFinal(baseString.getBytes(CHARSET_UTF8)); } public static String newStringByBase64(byte[] bytes) throws UnsupportedEncodingException { if (bytes == null || bytes.length == 0) { return null; } return new String(Base64.encodeBase64(bytes, false), CHARSET_UTF8); } public static void main(String[] args) { String str = "GET&%2F&AccessKeyId%3DCd***eHJuMOrT%26Action%3DDescribeInstances%26Format%3DJSON%26RegionId%3Dcn-hangzhou%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D9fdf288**36082ebef%26SignatureVersion%3D1.0%26Timestamp%3D2015-12-21T09%253A05%253A44Z%26Version%3D2014-05-26"; byte[] signBytes; try { signBytes = SignatureUtils.hmacSHA1Signature("byc****6HQmH" + "&", str.toString()); String signature = SignatureUtils.newStringByBase64(signBytes); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
//测试代码 private static String getQueryUrl(Mapparam) throws Exception { Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); simpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT")); String timestamp = simpleDateFormat.format(date); Map publicParam = Maps.newHashMap(); publicParam.put("AccessKeyId", accessKeyId); publicParam.put("Format", "json"); publicParam.put("SignatureMethod", "Hmac-SHA1"); publicParam.put("SignatureNonce", UUID.randomUUID().toString()); publicParam.put("SignatureVersion", "1.0"); publicParam.put("Timestamp", timestamp); publicParam.put("Version", "2014-05-15"); publicParam.put("RegionId", "cn-shanghai"); if (param != null) { for (Map.Entry entry : param.entrySet()) { publicParam.put(entry.getKey(), entry.getValue()); } } String s = SignatureUtils.generateSignString("GET", publicParam); byte[] signBytes; signBytes = SignatureUtils.hmacSHA1Signature(secret + "&", s); String signature = SignatureUtils.newStringByBase64(signBytes); publicParam.put("signature", signature); String url = "http://slb.aliyuncs.com/?"; //对参数进行url编码 for (Map.Entry entry : publicParam.entrySet()) { publicParam.put(entry.getKey(), URLEncoder.encode(entry.getValue().toString(), "UTF-8")); } //拼接请求url for (Map.Entry entry : publicParam.entrySet()) { url = url + entry + "&"; } //去掉最后一个& url = url.substring(0, url.length() - 1); return url; } public static void main(String[] args) { try { Map map = Maps.newHashMap(); map.put("Action", "DescribeLoadBalancerAttribute"); map.put("LoadBalancerId", "lb-********"); String url = getQueryUrl(map); System.err.println("\n" + url); } catch (Exception e) { e.printStackTrace(); } finally { } }
参考 https://help.aliyun.com/document_detail/28618.html