i have tried several links from stackoverflow to get HmacSHA256 with key to work with java, but i always get
func check(body: String) -> String {
let hash = body.hmac(HMACAlgorithm.sha256, key: Router.sigKey)
print("SIG: " + Router.sigKey)
print("result of hash. \(hash)")
return hash
}
This function returns hash with key from given String. Key was: 0393e944ee8108bb66fc9fa4f99f9c862481e9e0519e18232ba61b0767eee8c6
String was: example
Result is: 27effb76c97022497e25d3a5d7e823462f212a82d9ebba35f179071568b0c335
When i use this website to check if my SHA256 is good with the same key, it returns same answer, so i know my code in swift is good. But when i try to do it in java, here is the source code.
public static String HMAC_SHA(){
try {
String secret = "0393e944ee8108bb66fc9fa4f99f9c862481e9e0519e18232ba61b0767eee8c6";
String message = "example";
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = android.util.Base64.encodeToString(sha256_HMAC.doFinal(message.getBytes()), Base64.URL_SAFE);
return new String(Hex.encodeHex(hash.getBytes()));
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
It returns this: 4a2d5f3764736c77496b6c2d4a644f6c312d676a526938684b6f4c5a36376f3138586b4846576977777a553d0a
Which is not even similar to the swift output. How can i achieve the same result with java from the swift code above, it would be helpful a lot!
String key = "0393e944ee8108bb66fc9fa4f99f9c862481e9e0519e18232ba61b0767eee8c6";
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
sha256_HMAC.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"));
byte[] result = sha256_HMAC.doFinal("example".getBytes());
System.out.println (DatatypeConverter.printHexBinary(result));
// ONLY CONVERT TO HEX (= SWIFT) NOT FIRST TO BASE64
result as requested
27EFFB76C97022497E25D3A5D7E823462F212A82D9EBBA35F179071568B0C335
Your key contains values greater then the value 127 and, Mac
and SecretKeySpec
use byte
s, which in Java can contain values from -128 to 127.
In the HmacSHA256 algorithm, the key is interpreted as a string of hexadecimal values. In the case of your secret, the decimal values of this key are:
3,147,233,68,238,129,8,187,102,252,159,164,249,159,156,134,36,129,233,224,81,158,24,35,43,166,27,7,103,238,232,198
As you can see, some of them have a value over 127. When creating the SecretKeySpec
object and while doing calculations within the Mac
class, Java uses byte[]
to store this and related sequences. In Java, a byte
can contain values from -128 to 127, which means that when storing this secret, the values > 127 will "flip" and will make sure the calculations following this will not go as you'd expect.
In the Swift case (and with C++, Ruby, and other languages), the conversion from hex to byte occurs without losing the actual value.
来源:https://stackoverflow.com/questions/46988540/java-hmacsha256-with-key