Recently I was working on a grails project that consumes service hooks from another web application. As part of API authentication, I was required to use the sha256 algorithm to generate an
HMAC hash of a "calculated token" using a "secret key" as the salt. The following is what worked for me after several unsuccessful attempts (it's mainly java code):
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
/**
* @param secretKey
* @param data
* @return HMAC/SHA256 representation of the given string
*/
def hmac_sha256(String secretKey, String data) {
try { SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256")
Mac mac = Mac.getInstance("HmacSHA256")
mac.init(secretKeySpec)
byte[] digest = mac.doFinal(data.getBytes("UTF-8"))
return byteArrayToString(digest)
} catch (InvalidKeyException e) { throw new RuntimeException("Invalid key exception while converting to HMac SHA256")
}
}
private def byteArrayToString(byte[] data) {
BigInteger bigInteger = new BigInteger(1, data)
String hash = bigInteger.toString(16)
//Zero pad it
while (hash.length() < 64) {
hash = "0" + hash
}
return hash
}
To generate SHA256 HMAC hash, call the method hmac_sha256 supplying the required parameters as as shown below:
hmac_sha256("The secret key", "The data to hash")
Hint: You can use other SHA hashing algorithms in place of "HmacSHA256" e.g. HmacSHA1.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
/**
* @param secretKey
* @param data
* @return HMAC/SHA256 representation of the given string
*/
def hmac_sha256(String secretKey, String data) {
try { SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256")
Mac mac = Mac.getInstance("HmacSHA256")
mac.init(secretKeySpec)
byte[] digest = mac.doFinal(data.getBytes("UTF-8"))
return byteArrayToString(digest)
} catch (InvalidKeyException e) { throw new RuntimeException("Invalid key exception while converting to HMac SHA256")
}
}
private def byteArrayToString(byte[] data) {
BigInteger bigInteger = new BigInteger(1, data)
String hash = bigInteger.toString(16)
//Zero pad it
while (hash.length() < 64) {
hash = "0" + hash
}
return hash
}
To generate SHA256 HMAC hash, call the method hmac_sha256 supplying the required parameters as as shown below:
hmac_sha256("The secret key", "The data to hash")
Hint: You can use other SHA hashing algorithms in place of "HmacSHA256" e.g. HmacSHA1.
Very cool. Thanks for this! I referenced your post and adapted the code in one of my own posts.
ReplyDelete