java equivalent to php's hmac-SHA1

JavaPhpCryptographyHmac

Java Problem Overview


I'm looking for a java equivalent to this php call:

hash_hmac('sha1', "test", "secret")

I tried this, using java.crypto.Mac, but the two do not agree:

String mykey = "secret";
String test = "test";
try {
    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(mykey.getBytes(),"HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(test.getBytes());
    String enc = new String(digest);
    System.out.println(enc);  
} catch (Exception e) {
    System.out.println(e.getMessage());
}

The outputs with key = "secret" and test = "test" do not seem to match.

Java Solutions


Solution 1 - Java

In fact they do agree.
As Hans Doggen already noted PHP outputs the message digest using hexadecimal notation unless you set the raw output parameter to true.
If you want to use the same notation in Java you can use something like

for (byte b : digest) {
    System.out.format("%02x", b);
}
System.out.println();

to format the output accordingly.

Solution 2 - Java

You can try this in Java:

private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException {

    SecretKey secretKey = null;

    byte[] keyBytes = keyString.getBytes();
    secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");

    Mac mac = Mac.getInstance("HmacSHA1");

    mac.init(secretKey);

    byte[] text = baseString.getBytes();

    return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
}

Solution 3 - Java

This is my implementation :

        String hmac = "";

    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(llave.getBytes(), "HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(cadena.getBytes());
    BigInteger hash = new BigInteger(1, digest);
    hmac = hash.toString(16);

    if (hmac.length() % 2 != 0) {
        hmac = "0" + hmac;
    }

    return hmac;

Solution 4 - Java

Seems to me that PHP uses HEX notation for the bytes that Java produces (1a = 26) - but I didn't check the whole expression.

What happens if you run the byte array through the method on this page?

Solution 5 - Java

My implementation for HmacMD5 - just change algorithm to HmacSHA1:

SecretKeySpec keySpec = new SecretKeySpec("secretkey".getBytes(), "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] hashBytes = mac.doFinal("text2crypt".getBytes());
return Hex.encodeHexString(hashBytes);

Solution 6 - Java

This way I could get the exact same string as I was getting with hash_hmac in php

String result;

try {
		String data = "mydata";
		String key = "myKey";
		// 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(data.getBytes());

		// Convert raw bytes to Hex
		byte[] hexBytes = new Hex().encode(rawHmac);

		//  Covert array of Hex bytes to a String
		result = new String(hexBytes, "ISO-8859-1");
		out.println("MAC : " + result);
}
catch (Exception e) {
		
}

Solution 7 - Java

Haven't tested it, but try this:

		BigInteger hash = new BigInteger(1, digest);
		String enc = hash.toString(16);
		if ((enc.length() % 2) != 0) {
			enc = "0" + enc;
		}

This is snapshot from my method that makes java's md5 and sha1 match php.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBeeView Question on Stackoverflow
Solution 1 - JavaDirk DView Answer on Stackoverflow
Solution 2 - JavadharanView Answer on Stackoverflow
Solution 3 - JavaatomsfatView Answer on Stackoverflow
Solution 4 - JavaHans DoggenView Answer on Stackoverflow
Solution 5 - JavaKrizkoView Answer on Stackoverflow
Solution 6 - JavaAkhilView Answer on Stackoverflow
Solution 7 - JavasergView Answer on Stackoverflow