/* * [TestHMAC.java] * * Summary: Compute an HMAC, in particular use it to sign a message to the Amazon API. * * Copyright: (c) 2012-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2012-02-17 initial version */ package com.mindprod.example; import com.mindprod.base64.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import static java.lang.System.*; /** * Compute an HMAC, in particular use it to sign a message to the Amazon API. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2012-02-17 initial version * @since 2012-02-17 */ public final class TestHMAC { /** * Amazon SOAP transaction we need to sign. * Note the three lines prepended, not part of the message proper. * Note precisely where the ?s, &s and \ns are. They are all included in the digest. * Even a tiny difference will totally change the digest signature. */ private static final String MESSAGE_TO_SIGN = "GET\n" + "ecs.amazonaws.com\n" + "/onca/xml\n" + "AWSAccessKeyId=AKIAI53YWBAHR25L72BAAKIAI53YWBAHR25L72BA" + "&AssociateTag=canadianmindprod" + "&IdType=EAN" + "&ItemId=9781880418116" + "&Operation=ItemLookup" + "&ResponseGroup=Small" + "&SearchIndex=Books" + "&Service=AWSECommerceService" + "&Timestamp=2012-02-18T02%3A32%3A03.000Z" + "&Version=2010-11-01"; /** * shared secret key, assigned by Amazon, plucked from the environment, note getenv not getEnv. */ private static final String SHARED_SECRET_KEY = getenv( "awssecretaccesskey" ); /** * Compute the HMAC checksum of a transaction to the Amazon AWS API.. * * @param args not used * * @throws java.security.SignatureException if some problem computing the digital signature. * @throws java.security.InvalidKeyException if there is some problem with the shared secret key. * @throws java.security.NoSuchAlgorithmException if HmacSHA256 is not supported. */ public static void main( String[] args ) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException { // get AN HmacSHA256 key from the raw key bytes SecretKeySpec signingKey = new SecretKeySpec( SHARED_SECRET_KEY.getBytes(), "HmacSHA256" ); // get an Hmac_SHA1 Mac instance and initialize with the signing key Mac mac = Mac.getInstance( "HmacSHA256" ); mac.init( signingKey ); // compute the HMAC digest as a string of bytes. byte[] rawHMAC = mac.doFinal( MESSAGE_TO_SIGN.getBytes() ); // Base64 is available with source from http://mindprod.com/products.html#BASE64 String armouredHMAC = new Base64().encode( rawHMAC ); out.println( armouredHMAC ); // prints out something like: oXzRbvaDPz+Guwz1KXQSaoF8eHoeSamcR3Vtfvan5/Y= // To use, tack that on the end of your transaction, URL-Encoded // then your URL looks something like this all one line: // https://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=AKIAI53YWBAHR25L72BAAKIAI53YWBAHR25L72BA // &AssociateTag=canadianmindprod // &IdType=EAN // &ItemId=9781880418116 // &Operation=ItemLookup // &ResponseGroup=Small // &SearchIndex=Books // &Service=AWSECommerceService // &Timestamp=2012-02-18T02%3A32%3A03.000Z // &Version=2010-11-01 // &Signature=oXzRbvaDPz%2BGuwz1KXQSaoF8eHoeSamcR3Vtfvan5%2FY%3D- } }