全部产品
阿里云办公

签名算法参考

更新时间:2017-06-07 13:26:11

以下是Java版签名算法参考和C++版签名算法参考

Java签名算法参考

签名代码:UrlUtil.java

  1. import java.net.URLEncoder;
  2. import java.util.Map;
  3. import org.apache.commons.lang.StringUtils;
  4. import org.apache.log4j.Logger;
  5. public class UrlUtil {
  6. private static Logger logger = Logger.getLogger(UrlUtil.class);
  7. private final static String CHARSET_UTF8 = "utf8";
  8. /**
  9. *
  10. * @param url
  11. * @return
  12. */
  13. public static String urlEncode(String url) {
  14. if (!StringUtils.isEmpty(url)) {
  15. try {
  16. url = URLEncoder.encode(url, "UTF-8");
  17. } catch (Exception e) {
  18. logger.warn("Url encode error:" + e.getMessage());
  19. }
  20. }
  21. return url;
  22. }
  23. public static String generateQueryString(Map<String, String> params, boolean isEncodeKV) {
  24. StringBuilder canonicalizedQueryString = new StringBuilder();
  25. for (Map.Entry<String, String> entry : params.entrySet()) {
  26. if (isEncodeKV)
  27. canonicalizedQueryString.append(percentEncode(entry.getKey())).append("=")
  28. .append(percentEncode(entry.getValue())).append("&");
  29. else
  30. canonicalizedQueryString.append(entry.getKey()).append("=")
  31. .append(entry.getValue()).append("&");
  32. }
  33. if (canonicalizedQueryString.length() > 1) {
  34. canonicalizedQueryString.setLength(canonicalizedQueryString.length() - 1);
  35. }
  36. return canonicalizedQueryString.toString();
  37. }
  38. public static String percentEncode(String value) {
  39. try {
  40. // 使用URLEncoder.encode编码后,将"+","*","%7E"做替换即满足 API规定的编码规范
  41. return value == null ? null : URLEncoder.encode(value, CHARSET_UTF8)
  42. .replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
  43. } catch (Exception e) {
  44. //不可能发生的异常
  45. }
  46. return "";
  47. }
  48. }

SignatureUtils.java

  1. import java.io.IOException;
  2. import java.io.UnsupportedEncodingException;
  3. import java.net.URI;
  4. import java.net.URISyntaxException;
  5. import java.net.URLDecoder;
  6. import java.net.URLEncoder;
  7. import java.util.Map;
  8. import java.util.TreeMap;
  9. import javax.crypto.Mac;
  10. import javax.crypto.spec.SecretKeySpec;
  11. import org.apache.commons.codec.binary.Base64;
  12. import org.apache.commons.lang.StringUtils;
  13. public class SignatureUtils {
  14. private final static String CHARSET_UTF8 = "utf8";
  15. private final static String ALGORITHM = "UTF-8";
  16. private final static String SEPARATOR = "&";
  17. public static Map<String, String> splitQueryString(String url)
  18. throws URISyntaxException, UnsupportedEncodingException {
  19. URI uri = new URI(url);
  20. String query = uri.getQuery();
  21. final String[] pairs = query.split("&");
  22. TreeMap<String, String> queryMap = new TreeMap<String, String>();
  23. for (String pair : pairs) {
  24. final int idx = pair.indexOf("=");
  25. final String key = idx > 0 ? pair.substring(0, idx) : pair;
  26. if (!queryMap.containsKey(key)) {
  27. queryMap.put(key, URLDecoder.decode(pair.substring(idx + 1), CHARSET_UTF8));
  28. }
  29. }
  30. return queryMap;
  31. }
  32. public static String generate(String method, Map<String, String> parameter,
  33. String accessKeySecret) throws Exception {
  34. String signString = generateSignString(method, parameter);
  35. System.out.println("signString---"+signString);
  36. byte[] signBytes = hmacSHA1Signature(accessKeySecret + "&", signString);
  37. String signature = newStringByBase64(signBytes);
  38. System.out.println("signature---"+signature);
  39. if ("POST".equals(method))
  40. return signature;
  41. return URLEncoder.encode(signature, "UTF-8");
  42. }
  43. public static String generateSignString(String httpMethod, Map<String, String> parameter)
  44. throws IOException {
  45. TreeMap<String, String> sortParameter = new TreeMap<String, String>();
  46. sortParameter.putAll(parameter);
  47. String canonicalizedQueryString = UrlUtil.generateQueryString(sortParameter, true);
  48. if (null == httpMethod) {
  49. throw new RuntimeException("httpMethod can not be empty");
  50. }
  51. StringBuilder stringToSign = new StringBuilder();
  52. stringToSign.append(httpMethod).append(SEPARATOR);
  53. stringToSign.append(percentEncode("/")).append(SEPARATOR);
  54. stringToSign.append(percentEncode(canonicalizedQueryString));
  55. return stringToSign.toString();
  56. }
  57. public static String percentEncode(String value) {
  58. try {
  59. return value == null ? null : URLEncoder.encode(value, CHARSET_UTF8)
  60. .replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
  61. } catch (Exception e) {
  62. }
  63. return "";
  64. }
  65. public static byte[] hmacSHA1Signature(String secret, String baseString)
  66. throws Exception {
  67. if (StringUtils.isEmpty(secret)) {
  68. throw new IOException("secret can not be empty");
  69. }
  70. if (StringUtils.isEmpty(baseString)) {
  71. return null;
  72. }
  73. Mac mac = Mac.getInstance("HmacSHA1");
  74. SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), ALGORITHM);
  75. mac.init(keySpec);
  76. return mac.doFinal(baseString.getBytes(CHARSET_UTF8));
  77. }
  78. public static String newStringByBase64(byte[] bytes)
  79. throws UnsupportedEncodingException {
  80. if (bytes == null || bytes.length == 0) {
  81. return null;
  82. }
  83. return new String(Base64.encodeBase64(bytes, false), CHARSET_UTF8);
  84. }
  85. public static void main(String[] args) {
  86. String str = "GET&%2F&AccessKeyId%3DCdwKFNmXeHJuMOrT%26Action%3DDescribeInstances%26Format%3DJSON%26RegionId%3Dcn-hangzhou%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D9fdf20f2-9a32-4872-bcd4-c6036082ebef%26SignatureVersion%3D1.0%26Timestamp%3D2015-12-21T09%253A05%253A44Z%26Version%3D2014-05-26";
  87. byte[] signBytes;
  88. try {
  89. signBytes = SignatureUtils.hmacSHA1Signature("byczfpx4PKBzUNjjL4261cE3s6HQmH" + "&", str.toString());
  90. String signature = SignatureUtils.newStringByBase64(signBytes);
  91. } catch (Exception e) {
  92. // TODO Auto-generated catch block
  93. e.printStackTrace();
  94. }
  95. }
  96. }

C++ 签名算法参考

  1. #include "ali_rpc_request.h"
  2. #include "ali_string_utils.h"
  3. #include "ali_encode_utils.h"
  4. #include "ali_urlencode.h"
  5. #include "ali_log.h"
  6. #include <stdio.h>
  7. #include <time.h>
  8. static std::string get_utc_string() {
  9. time_t now;
  10. struct tm *timenow;
  11. now = time(&now);
  12. timenow = gmtime(&now);
  13. std::string res= get_format_string("%d-%02d-%02dT%02d:%02d:%02dZ", timenow->tm_year + 1900,
  14. timenow->tm_mon + 1,
  15. timenow->tm_mday,
  16. timenow->tm_hour,
  17. timenow->tm_min,
  18. timenow->tm_sec);
  19. return res;
  20. }
  21. AliRpcRequest::AliRpcRequest(std::string version,
  22. std::string appid,
  23. std::string secret,
  24. std::string url)
  25. : AliHttpRequest(url),
  26. version_(version),
  27. appid_(appid),
  28. secret_(secret),
  29. url_(url) {
  30. }
  31. std::string AliRpcRequest::GetSignUrl() {
  32. std::string encoded;
  33. std::map<std::string, std::string> mapWithPublicArgs;
  34. time_t now;
  35. time(&now);
  36. this->sign_nounce = get_format_string("%ld", now);
  37. this->utc_time_ = get_utc_string();
  38. if(this->query_.size()) {
  39. std::vector<std::string> vec_queries;
  40. strsplit(this->query_, vec_queries, "&");
  41. for(int i = 0; i < vec_queries.size(); i++) {
  42. std::string& item = vec_queries[i];
  43. int pos = item.find("=");
  44. mapWithPublicArgs[item.substr(0, pos)] = item.substr(pos + 1, item.size() - pos - 1);
  45. }
  46. }
  47. mapWithPublicArgs["Format"] = "JSON";
  48. mapWithPublicArgs["Version"] = this->version_;
  49. mapWithPublicArgs["AccessKeyId"] = this->appid_;
  50. mapWithPublicArgs["SignatureMethod"] = "HMAC-SHA1";
  51. mapWithPublicArgs["TimeStamp"] = utc_time_;
  52. mapWithPublicArgs["SignatureVersion"] = "1.0";
  53. mapWithPublicArgs["SignatureNonce"] = sign_nounce;//
  54. for(std::map<std::string, std::string>::iterator it = mapWithPublicArgs.begin();
  55. it != mapWithPublicArgs.end(); it++) {
  56. if(!encoded.empty()) {
  57. encoded.append("&");
  58. }
  59. append_format_string(encoded, "%s=%s", urlencode(it->first).c_str(), urlencode(it->second).c_str());
  60. }
  61. encoded = this->method_ + "&" + urlencode("/") + "&" + urlencode(encoded);
  62. ALI_LOG("sign str=%s\n", encoded.c_str());
  63. return encoded;
  64. }
  65. int AliRpcRequest::CommitRequest() {
  66. std::string sign_url = GetSignUrl();
  67. std::string sign = encode_compute_hmac_sha1(this->secret_ + "&",
  68. (char*)sign_url.c_str(),
  69. sign_url.size());
  70. AddRequestQuery("TimeStamp", utc_time_);
  71. AddRequestQuery("Format", "JSON");
  72. AddRequestQuery("Version", this->version_);
  73. AddRequestQuery("AccessKeyId", this->appid_);
  74. AddRequestQuery("SignatureMethod", "HMAC-SHA1");
  75. AddRequestQuery("SignatureVersion", "1.0");
  76. AddRequestQuery("SignatureNonce", this->sign_nounce);
  77. AddRequestQuery("Signature", sign);
  78. return AliHttpRequest::CommitRequest();
  79. }
本文导读目录