How to create HMAC in Java equivalent to Python example?

I am looking for an implementation of an application that receives Twitter authorization through Oauth in Java. The first step is to get the request token . Here is a Python example for the application engine.

To test my code, I run Python and test the output using Java. Here is a Python example generating a Hash-based message authentication code (HMAC):

#!/usr/bin/python from hashlib import sha1 from hmac import new as hmac key = "qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50" message = "foo" print "%s" % hmac(key, message, sha1).digest().encode('base64')[:-1] 

Output:

 $ ./foo.py +3h2gpjf4xcynjCGU5lbdMBwGOc= 

How to replicate this example in Java?

I saw an HMAC example in Java:

 try { // Generate a key for the HMAC-MD5 keyed-hashing algorithm; see RFC 2104 // In practice, you would save this key. KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5"); SecretKey key = keyGen.generateKey(); // Create a MAC object using HMAC-MD5 and initialize with key Mac mac = Mac.getInstance(key.getAlgorithm()); mac.init(key); String str = "This message will be digested"; // Encode the string into bytes using utf-8 and digest it byte[] utf8 = str.getBytes("UTF8"); byte[] digest = mac.doFinal(utf8); // If desired, convert the digest into a string String digestB64 = new sun.misc.BASE64Encoder().encode(digest); } catch (InvalidKeyException e) { } catch (NoSuchAlgorithmException e) { } catch (UnsupportedEncodingException e) { } 

It uses javax.crypto.Mac , all is well. However, SecretKey constructors accept bytes and an algorithm.

What is the example of Python? How to create Java secret key without algorithm?

+45
java oauth hmac sha1 cryptoapi
Jul 08 '10 at 21:31
source share
2 answers

HmacSHA1 is the name of the algorithm you need:

 SecretKeySpec keySpec = new SecretKeySpec( "qnscAdgRlkIhAUPY44oiexBKtQbGY0orf7OV1I50".getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(keySpec); byte[] result = mac.doFinal("foo".getBytes()); BASE64Encoder encoder = new BASE64Encoder(); System.out.println(encoder.encode(result)); 

gives:

 +3h2gpjf4xcynjCGU5lbdMBwGOc= 

Note that I used sun.misc.BASE64Encoder for a quick implementation here, but you should probably use something that is not dependent on the Sun JRE. A basic 64 encoder in Commons Codec would be a better choice, for example.

+64
Jul 08 2018-10-10T00:
source share

An insignificant thing, but if you are looking for the equivalent of hmac (key, message), then by default the python library will use the MD5 algorithm, so you need to use the HmacMD5 algorithm in Java.

I mention this because I had this exact problem and found this answer that was useful, but I skipped the part where the digest method was passed to hmac (), and thus went down the rabbit hole. I hope this answer does not allow others to do the same in the future.

eg. in Python REPL

 >>> import hmac >>> hmac.new("keyValueGoesHere", "secretMessageToHash").hexdigest() '1a7bb3687962c9e26b2d4c2b833b2bf2' 

This is equivalent to the Java method:

 import org.apache.commons.codec.binary.Hex; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class HashingUtility { public static String HMAC_MD5_encode(String key, String message) throws Exception { SecretKeySpec keySpec = new SecretKeySpec( key.getBytes(), "HmacMD5"); Mac mac = Mac.getInstance("HmacMD5"); mac.init(keySpec); byte[] rawHmac = mac.doFinal(message.getBytes()); return Hex.encodeHexString(rawHmac); } } 

Note that in my example, I am making the equivalent of .hexdigest ()

+19
Jun 19 2018-12-12T00:
source share



All Articles