/* * Copyright 2007-2008 Amazon Technologies, Inc. * * 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://aws.amazon.com/apache2.0 * * This file 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.amazonaws.mturk.util; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimeZone; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.axis.encoding.Base64; /** * The HMACSigner class contains methods to sign strings using HMAC-SHA1 algorithm. * * @see http://docs.amazonwebservices.com/AWSMechanicalTurkRequester/2006-10-31/MakingRequests_RequestAuthenticationArticle.html */ public class HMACSigner { //------------------------------------------------------------- // Constants - Private //------------------------------------------------------------- private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1"; private static final SimpleDateFormat gmtFormat; //------------------------------------------------------------- // Variables - Private //------------------------------------------------------------- private Mac mac; static { // This format must match the Axis format exactly gmtFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); gmtFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } //------------------------------------------------------------- // Constructors //------------------------------------------------------------- /** * @param key Key must be ASCII and correct. */ public HMACSigner(String key) { // Get an hmac_sha1 key from the raw key bytes SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM); // Get an hmac_sha1 Mac instance and initialize with the signing key Mac mac = null; try { mac = Mac.getInstance(HMAC_SHA1_ALGORITHM); mac.init(signingKey); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (InvalidKeyException e) { throw new RuntimeException(e); } this.mac = mac; } //------------------------------------------------------------- // Methods - Public //------------------------------------------------------------- /** * Creates a signature based on the given parameters. * * @param service Name of the AWS service * @param operation Name of the operation as defined in the WSDL * @param timestamp Time instance that is included in the request * @return A signature */ public String sign(String service, String operation, Calendar timestamp) { String stringToSign = service + operation + gmtFormat.format(timestamp.getTime()); return sign(stringToSign); } /** * Creates a signature based on the given parameters. * * @param toSign A string to sign * @return A signature */ public String sign(String toSign) { // compute the hmac on input data bytes byte[] rawHmac = mac.doFinal(toSign.getBytes()); // base64-encode the hmac return Base64.encode(rawHmac); } }