Skip to content

Instantly share code, notes, and snippets.

@smulube
Last active November 15, 2017 13:38
Show Gist options
  • Save smulube/5859624 to your computer and use it in GitHub Desktop.
Save smulube/5859624 to your computer and use it in GitHub Desktop.
Java helper to generate a hex SHA1 HMAC suitable for generating device activation code for Xively.
// Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved.
// This is part of Xively4J library, it is under the BSD 3-Clause license.
package com.xively.client.utils;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HmacUtils {
/**
* General hmac method - can pass in any crypto string recognised by
* {@link Mac.getInstance}.
*
* @param crypto
* @param key
* @param value
* @return
*/
public static String hmacSha(String crypto, String key, String value) {
try {
byte[] keyBytes = hexStr2Bytes(key);
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return bytesToHex(hmac.doFinal(value.getBytes()));
} catch (GeneralSecurityException gse) {
throw new RuntimeException(gse);
}
}
/**
* Convenience method to generate the HMAC-SHA1 signatures we are using in
* this application.
*
* @param key
* @param value
* @return
*/
public static String hmacSha1(String key, String value) {
return hmacSha("HmacSHA1", key, value);
}
/**
* Convert hex string into byte array.
*
* @param hex
* @return
*/
private static byte[] hexStr2Bytes(String hex) {
// Adding one byte to get the right conversion
// Values starting with "0" can be converted
byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
// Copy all the REAL bytes, not the "first"
byte[] ret = new byte[bArray.length - 1];
for (int i = 0; i < ret.length; i++)
ret[i] = bArray[i + 1];
return ret;
}
/**
*
* Convert a byte array into a hex string
*
* @param bytes
* @return
*/
private static String bytesToHex(byte[] bytes) {
final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
// Copyright (c) 2003-2013, LogMeIn, Inc. All rights reserved.
// This is part of Xively4J library, it is under the BSD 3-Clause license.
package com.xively.client.utils;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class HmacUtilsTest {
@Test
public void generatingHmac() {
String key = "377f93e5649c31635191c0e22258f5a5744698d3";
String value = "0001";
String hmac = "13bf6065634a624104cfa14a1f977bede2aa39d8";
assertEquals(hmac, HmacUtils.hmacSha1(key, value));
}
@Test
public void generatingHmacViaGeneralMethod() {
String key = "377f93e5649c31635191c0e22258f5a5744698d3";
String value = "0001";
String hmac = "13bf6065634a624104cfa14a1f977bede2aa39d8";
assertEquals(hmac, HmacUtils.hmacSha("HmacSHA1", key, value));
}
@Test(expected = RuntimeException.class)
public void invalidCrypto() {
HmacUtils.hmacSha("foo", "key", "value");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment