Java tutorial
/* * Copyright (C) 2012 kkurahar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.kku.apps.pricesearch.util; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TimeZone; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class SignedHelper { private static final String SEPARATOR = "|"; private static final String ENCODING = "UTF-8"; private static final String ALGORITHM = "HmacSHA256"; private static final String HTTPMETHOD = "GET"; /** * ??l???B * * @param secretKey * API?B * @param url * http://api.7netshopping.jp/ws/affiliate/[rest|soap]/[ * NGXg?bZ?[W] `URL?B * @param params * NGXgp??[^(Signature?)?B * @return ??l?B * @throws Exception * ??????O??B */ public static String createSignatureValue(String secretKey, String url, Map<String, String> params) throws Exception { params.put("Timestamp", timestamp()); String targetString = createTargetString(url, params); String sig = sign(secretKey, targetString); SortedMap<String, String> sortedParamMap = new TreeMap<String, String>(params); String canonicalQS = canonicalize(sortedParamMap); String rUrl = url + "?" + canonicalQS + "&Signature=" + sig; return rUrl; } private static String createTargetString(String url, Map<String, String> params) throws Exception { List<String> paramsList = createParamsList(params); StringBuilder sb = new StringBuilder(); for (String keyAndValue : paramsList) { sb.append(SEPARATOR); sb.append(keyAndValue); } String parameters = sb.toString(); String sourceString = String.format("%s%s%s%s", HTTPMETHOD, SEPARATOR, url, parameters); return percentEncodeRfc3986(sourceString); } private static List<String> createParamsList(Map<String, String> params) { List<String> paramsList = new ArrayList<String>(params.size()); for (Map.Entry<String, String> map : params.entrySet()) { paramsList.add(String.format("%s=%s", map.getKey(), map.getValue())); } Collections.sort(paramsList); return paramsList; } private static String sign(String apiSecretKey, String sourceString) throws Exception { SecretKeySpec secretKeySpec = new SecretKeySpec(apiSecretKey.getBytes(ENCODING), ALGORITHM); Mac mac = Mac.getInstance(ALGORITHM); mac.init(secretKeySpec); byte[] data = mac.doFinal(sourceString.getBytes(ENCODING)); Base64 encoder = new Base64(); String signature = new String(encoder.encode(data)); return signature; } private static String percentEncodeRfc3986(String s) { String out; try { out = URLEncoder.encode(s, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); } catch (UnsupportedEncodingException e) { out = s; } return out; } private static String timestamp() { String timestamp = null; Calendar cal = Calendar.getInstance(); DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); dfm.setTimeZone(TimeZone.getTimeZone("GMT")); timestamp = dfm.format(cal.getTime()); return timestamp; } private static String canonicalize(SortedMap<String, String> sortedParamMap) { if (sortedParamMap.isEmpty()) { return ""; } StringBuffer buffer = new StringBuffer(); Iterator<Map.Entry<String, String>> iter = sortedParamMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry<String, String> kvpair = iter.next(); buffer.append(percentEncodeRfc3986(kvpair.getKey())); buffer.append("="); buffer.append(percentEncodeRfc3986(kvpair.getValue())); if (iter.hasNext()) { buffer.append("&"); } } String cannoical = buffer.toString(); return cannoical; } }