Java HmacSHA256 with key

14,134
    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
Share:
14,134
Miljan Rakita
Author by

Miljan Rakita

Love to learn programming. Learning java and c. :)

Updated on June 13, 2022

Comments

  • Miljan Rakita
    Miljan Rakita about 2 years

    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!

  • Chris Brandhorst
    Chris Brandhorst almost 6 years
    I now see the following answer, which gives even more detail: stackoverflow.com/questions/47797100/…
  • Kayaman
    Kayaman almost 6 years
    The problem here is the call to getBytes(). The secret String should be parsed from hexadecimal, which is a completely different thing. In the question you linked it's done correctly with decodeHex.
  • dave_thompson_085
    dave_thompson_085 almost 6 years
    This is wrong. JVM treats byte as signed, but it's easy to make it unsigned by masking it and that's exactly what all JCE code does, and produces the correct result. In your code you should also do it correctly. @Kayaman: in the other Q yes; here the key looks hex but the swift code did NOT treat it as such, and the actual cause of the difference was double-encoding the output
  • Chris Brandhorst
    Chris Brandhorst almost 6 years
    @Kayaman I'm gonna need to evaluate in my usecase I was led to this conclusion. Thanks for the pointers.