28

Is there any function for creating Hmac256 string in android ? I am using php as my back end for my android application, in php we can create hmac256 string using the php function hash_hmac () [ ref ] is there any function like this in Android

Please help me.

Bikesh M
  • 8,163
  • 6
  • 40
  • 52
  • 1
    Have you tried using the [`Mac`](http://developer.android.com/reference/javax/crypto/Mac.html) class with `"Hmac256"` as the algorithm name? – Michael Mar 15 '16 at 07:19
  • no can you add syntax – Bikesh M Mar 15 '16 at 07:27
  • 1
    I'm sure you can find plenty of examples of how to use that class if you search around. – Michael Mar 15 '16 at 07:28
  • thanks, i tried Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); hash = Base64.encodeToString(sha256_HMAC.doFinal(message.getBytes()), Base64.DEFAULT); but this is giving wrong – Bikesh M Mar 15 '16 at 07:30
  • "this is giving wrong" - could you be more specific by any chance? – JHH Mar 15 '16 at 08:05
  • The result is not matching with the value which i have generated in server using php hash_hmac () function – Bikesh M Mar 15 '16 at 08:14

2 Answers2

33

Calculate the message digest with the hashing algorithm HMAC-SHA256 in the Android platform:

private void generateHashWithHmac256(String message, String key) {
    try {
        final String hashingAlgorithm = "HmacSHA256"; //or "HmacSHA1", "HmacSHA512"

        byte[] bytes = hmac(hashingAlgorithm, key.getBytes(), message.getBytes());

        final String messageDigest = bytesToHex(bytes);

        Log.i(TAG, "message digest: " + messageDigest);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static byte[] hmac(String algorithm, byte[] key, byte[] message) throws NoSuchAlgorithmException, InvalidKeyException {
    Mac mac = Mac.getInstance(algorithm);
    mac.init(new SecretKeySpec(key, algorithm));
    return mac.doFinal(message);
}

public static String bytesToHex(byte[] bytes) {
    final char[] hexArray = "0123456789abcdef".toCharArray();
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0, v; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

This approach does not require any external dependency.

Ryan Amaral
  • 4,059
  • 1
  • 41
  • 39
  • 1
    What does this mean final char[] hexArray = "0123456789abcdef".toCharArray(); – Kannan_SJD Jul 16 '19 at 12:19
  • Is an array of `char` that is initialised with the hexadecimal numeral system. The word 'hexadecimal' means sixteen because this type of digital numbering system uses 16 different digits from 0-to-9, and A-to-F. – Ryan Amaral May 18 '21 at 16:30
15

Try below code

public static String encode(String key, String data) throws Exception {
    Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
    sha256_HMAC.init(secret_key);

    return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

Hex.encodeHexString() to use this method, add below dependency to your app gradle.

compile 'org.apache.directory.studio:org.apache.commons.codec:1.8'

This will convert resulted string to hex string same as your php hash_hmac() funtion generates.

Chirag Chavda
  • 556
  • 4
  • 12
  • I am getting this using your method: error: cannot find symbol return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8"))); – f.trajkovski Feb 28 '19 at 16:23
  • 1
    Make sure you're importing the correct Hex object. Should be `org.apache.commons.codec.binary.Hex` (as specified in the dependency above) not `com.google.android.gms.common.util.Hex` – Jesse Buss Jun 20 '19 at 14:12