I'm trying to hash a message to a server side (which I can't change his code) written in php and encoded by HMAC_SHA1 algorithm. I'm writing the code in Java. the php code is as follows:
$utf8Str = mb_convert_encoding($strToSign, "UTF-8");
$hmac_sha1_str = base64_encode(hash_hmac("sha1", $utf8Str, KEY));
$signature = urlencode($hmac_sha1_str);
my java code is:
private static String HashStringSign(String toHash){
try {
String afterUTF = new String(toHash.getBytes(), "UTF-8");
String res = hmac_sha1(afterUTF, SecretAccessKey);
String signature = new String(Base64.encode(res.getBytes()));
String result = URLEncoder.encode(signature);
return result;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private static String hmac_sha1(String value, String key) {
try {
// Get an hmac_sha1 key from the raw key bytes
byte[] keyBytes = key.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
// Get an hmac_sha1 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
// Compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(value.getBytes());
// Convert raw bytes to Hex
byte[] hexBytes = new Hex().encode(rawHmac);
return new String(hexBytes, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I followed each of the hashing methods used in the php code and in the same order as you can see. maybe there's a function(s) in java that works different in php?
I'm using - com.sun.org.apache.xml.internal.security.utils.Base64 java.net.URLEncoder, javax.crypto and org.apache.commons.codec.binary
Thanks!
In your hash_hmac
function you need to set the 4th parameter to true.
So now you say that you can't change the PHP side, you can do the following to your Java code.
In your last step of the Java code, you converted the raw byte array to hexademical. However, PHP generates a base64-encoded hexademical instead of just hexademical.
So that the end of your Java step, simply base64 encode your hexademical and you will get the same values. https://stackoverflow.com/questions/9845767/base64-encoder-java#