001
014
015 package com.liferay.portlet.amazonrankings.util;
016
017 import com.liferay.portal.kernel.util.Base64;
018 import com.liferay.portal.kernel.util.StringBundler;
019 import com.liferay.portal.kernel.util.StringUtil;
020
021 import java.net.URLEncoder;
022
023 import java.util.Map;
024 import java.util.Set;
025 import java.util.TreeMap;
026
027 import javax.crypto.Mac;
028 import javax.crypto.spec.SecretKeySpec;
029
030 import jodd.util.StringPool;
031
032
036 public class AmazonSignedRequestsUtil {
037
038 public static String generateUrlWithSignature(
039 Map<String, String> parameters)
040 throws Exception {
041
042 String canonicalizedParameters = _canonicalizeParameters(parameters);
043
044 String signature = _generateSignature(
045 "GET\necs.amazonaws.com\n/onca/xml\n" + canonicalizedParameters);
046
047 return "http:
048 "&Signature=" + signature;
049 }
050
051 private static String _canonicalizeParameters(
052 Map<String, String> parameters)
053 throws Exception {
054
055 if (parameters.isEmpty()) {
056 return StringPool.EMPTY;
057 }
058
059 parameters = new TreeMap<String, String>(parameters);
060
061 Set<Map.Entry<String, String>> parametersSet = parameters.entrySet();
062
063 StringBundler sb = new StringBundler(parametersSet.size() * 4);
064
065 for (Map.Entry<String, String> parameter : parametersSet) {
066 sb.append(_rfc3986Encode(parameter.getKey()));
067 sb.append(StringPool.EQUALS);
068 sb.append(_rfc3986Encode(parameter.getValue()));
069 sb.append(StringPool.AMPERSAND);
070 }
071
072 sb.setIndex(sb.index() - 1);
073
074 return sb.toString();
075 }
076
077 private static String _generateSignature(String data) throws Exception {
078 String amazonSecretAccessKey =
079 AmazonRankingsUtil.getAmazonSecretAccessKey();
080
081 SecretKeySpec secretKeySpec = new SecretKeySpec(
082 amazonSecretAccessKey.getBytes(), _HMAC_SHA256_ALGORITHM);
083
084 Mac mac = Mac.getInstance(_HMAC_SHA256_ALGORITHM);
085
086 mac.init(secretKeySpec);
087
088 byte[] bytes = mac.doFinal(data.getBytes());
089
090 String signature = Base64.encode(bytes);
091
092 return StringUtil.replace(
093 signature, new String[] {StringPool.EQUALS, StringPool.PLUS},
094 new String[] {"%3D", "%2B"});
095 }
096
097 private static String _rfc3986Encode(String string) throws Exception {
098 string = URLEncoder.encode(string, StringPool.UTF_8);
099
100 string = StringUtil.replace(
101 string, new String[] {StringPool.ASTERISK, StringPool.PLUS, "%7E"},
102 new String[] {"%2A", "%2B", "~"});
103
104 return string;
105 }
106
107 private static final String _HMAC_SHA256_ALGORITHM = "HmacSHA256";
108
109 }