/* * © Copyright IBM Corp. 2013 * * 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.ibm.sbt.security.encryption; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Map; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import com.ibm.commons.util.StringUtil; import com.ibm.sbt.core.configuration.Configuration; import com.ibm.sbt.security.authentication.oauth.OAuthException; /** * HMACEncryptionUtility can be used to generate HMAC based signature for OAuth1 Authentication * <p> * * @author Manish Kataria * @author Vimal Dhupar */ public class HMACEncryptionUtility { public static String generateHMACSignature(String apiUrl, String method, String consumerSecret, String tokenSecret, Map<String, String> paramsSortedMap) throws OAuthException { try { String parameterString = generateParameterString(paramsSortedMap); String signature_base_string = generateSignatureBaseString(method, apiUrl, parameterString); String signingKey = null; if (StringUtil.isEmpty(tokenSecret)) { // No token secret is available when call is made from getRequestToken, tokensecret is fetched // later in OADance signingKey = consumerSecret + "&"; } else { signingKey = consumerSecret + "&" + tokenSecret; } byte[] keyBytes = null; try { keyBytes = signingKey.getBytes(Configuration.ENCODING); } catch (UnsupportedEncodingException e) { throw new OAuthException(e, "HMACEncryptionUtility : generateHMACSignature caused UnsupportedEncodingException exception"); } SecretKey secretKey = new SecretKeySpec(keyBytes, "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(secretKey); byte[] text = null; try { text = signature_base_string.getBytes(Configuration.ENCODING); } catch (UnsupportedEncodingException e) { throw new OAuthException(e, "HMACEncryptionUtility : generateHMACSignature caused UnsupportedEncodingException exception"); } String signature = new String(Base64.encodeBase64(mac.doFinal(text))).trim(); return signature; } catch (NoSuchAlgorithmException e) { throw new OAuthException(e, "HMACEncryptionUtility : generateHMACSignature caused NoSuchAlgorithmException exception"); } catch (InvalidKeyException e) { throw new OAuthException(e, "HMACEncryptionUtility : generateHMACSignature caused InvalidKeyException exception"); } } public static String percentEncode(String str) { String encodedStr = null; try { encodedStr = URLEncoder.encode(str, Configuration.ENCODING).replace("+", "%20") .replace("*", "%2A").replace("%7E", "~"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage()); } return encodedStr; } public static String generateParameterString(Map<String, String> paramsMap) { StringBuilder parameterString = new StringBuilder(); for (Map.Entry<String, String> entry : paramsMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); parameterString.append(key).append("=").append(percentEncode(value)).append("&"); } // Now remove the last & and return the string. return parameterString.deleteCharAt(parameterString.length() - 1).toString(); } public static String generateSignatureBaseString(String method, String url, String parameterString) throws OAuthException { StringBuilder signatureBaseString = new StringBuilder(); try { signatureBaseString.append(method.toUpperCase()).append("&").append(percentEncode(url)) .append("&").append(URLEncoder.encode(parameterString, "UTF-8")); } catch (UnsupportedEncodingException e) { throw new OAuthException(e, "HMACEncryptionUtility : generateSignatureBaseString caused UnsupportedEncodingException exception"); } return signatureBaseString.toString(); } }