package prestaAmazon;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class AccessAmazon {
public static void main(String[] args) throws SignatureException, UnsupportedEncodingException {
String timeStamp = getCurrentTimeStamp();
System.out.println(timeStamp);
String data = "GET"+"\n"+"webservices.amazon.co.uk"+"\n"+"/onca/xml"+"\n"+"AWSAccessKeyId=MY_AWS_KEY&AssociateTag=MY_TAG&Condition=New&IdType=ASIN&ItemId=B0087Y7E5K&Operation=ItemLookup&ResponseGroup=Offers&Service=AWSECommerceService&Timestamp=2013-07-03T18%3A42%3A00.000Z&Version=2011-08-01";
String key = "MY_SECRET_KEY";
String signature = calculateHMAC(data, key);
System.out.println(signature);
String restURL = "http://webservices.amazon.co.uk/onca/xml?AWSAccessKeyId=MY_AWS_KEY&AssociateTag=MY_TAG&Condition=New&IdType=ASIN&ItemId=B0087Y7E5K&Operation=ItemLookup&ResponseGroup=Offers&Service=AWSECommerceService&Timestamp=2013-07-03T18%3A42%3A00.000Z&Version=2011-08-01&Signature=" + signature;
System.out.println(restURL);
}
private static final String HMAC_SHA_ALGORITHM = "HmacSHA256";
public static String calculateHMAC(String data, String key)throws java.security.SignatureException{
try {
// get an hmac_sha256 key from the raw key bytes
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA_ALGORITHM);
// get an hmac_sha256 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance(HMAC_SHA_ALGORITHM);
mac.init(signingKey);
// compute the hmac256 on input data bytes
byte[] rawHmac = mac.doFinal(data.getBytes());
// base64-encode the hmac256
String result = new String(Base64.encodeBase64(rawHmac));
return URLEncoder.encode(result, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
} catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
}
public static String getCurrentTimeStamp() throws UnsupportedEncodingException {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ");
sdfDate.setTimeZone(TimeZone.getTimeZone("GMT"));
Date now = new Date();
String strDate = sdfDate.format(now);
return strDate.replaceFirst(" ", "T").replaceFirst(" ", "Z").replaceAll(":", "%3A");
}
}
问题是当复制粘贴字符串 - 从暂存器中签名并带有时间戳时,签名是正确的。意味着问题不在算法或执行它的部分。
现在,当我添加timeStamp时,我从调用getCurrentTimeStamp()获得了
像这样:"...Timestamp=" + timeStamp + "&...";
它不会生成正确的签名。
当我手动编写完全相同的Timestamp值并像使用变量timeStamp一样添加它时,它也不会这样做。
所以我认为问题出在String变量timeStamp的编码中。 任何人都可以告诉我如何正确编码java中的String变量timeStamp或者至少是什么编码是亚马逊的暂存器中的字符串到符号文本?