I've been trying to port some NodeJS code to Java in order to make HMAC signed requests to an API. I've been able to simplify the code to a point were encoding is clearly affecting the output.
Here's my code in JavaScript:
var APIKey = "secret";
var secretByteArray = CryptoJS.enc.Base64.parse(APIKey);
var hash = CryptoJS.HmacSHA256("Message", secretByteArray);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
//alert(hashInBase64);
document.write(hashInBase64);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac-sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
Here's the Java Code:
try {
String secret = "secret";
String message = "Message";
byte[] secretByteArray = Base64.getEncoder().encode(secret.getBytes());
//byte[] secretByteArray = Base64.encodeBase64(secret.getBytes("utf-8"), true);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretByteArray, "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(message.getBytes()));
System.out.println(hash);
}
catch (Exception e){
System.out.println("Error");
}
If I don't encode to base64 the "secret" I get the same output, but I'd like to get the same result with encoded strings. I suspect the encoded byte arrays have padding or sign differences.
Your Java code uses Base64.getEncoder().encode
to convert to Base64.
Your JavaScript code uses CryptoJS.enc.Base64.parse
to convert from Base64.
You need to make those match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With