Skip to content

Instantly share code, notes, and snippets.

@ishikawa
Created April 1, 2009 07:49
Show Gist options
  • Star 70 You must be signed in to star a gist
  • Fork 22 You must be signed in to fork a gist
  • Save ishikawa/88599 to your computer and use it in GitHub Desktop.
Save ishikawa/88599 to your computer and use it in GitHub Desktop.
Java Sample Code for Calculating HMAC-SHA1 Signatures
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* The <tt>HmacSha1Signature</tt> shows how to calculate
* a message authentication code using HMAC-SHA1 algorithm.
*
* <pre>
* % java -version
* java version "1.6.0_11"
* % javac HmacSha1Signature.java
* % java -ea HmacSha1Signature
* 104152c5bfdca07bc633eebd46199f0255c9f49d
* </pre>
*
*/
public class HmacSha1Signature {
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
private static String toHexString(byte[] bytes) {
Formatter formatter = new Formatter();
for (byte b : bytes) {
formatter.format("%02x", b);
}
return formatter.toString();
}
public static String calculateRFC2104HMAC(String data, String key)
throws SignatureException, NoSuchAlgorithmException, InvalidKeyException
{
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
return toHexString(mac.doFinal(data.getBytes()));
}
public static void main(String[] args) throws Exception {
String hmac = calculateRFC2104HMAC("data", "key");
System.out.println(hmac);
assert hmac.equals("104152c5bfdca07bc633eebd46199f0255c9f49d");
}
}
@aoberoi
Copy link

aoberoi commented Apr 14, 2014

thanks!

@xlarsx
Copy link

xlarsx commented Aug 21, 2014

Great!

@anzmage
Copy link

anzmage commented Jun 4, 2015

thanks man!

@jorawarsingh
Copy link

Thanks!

@danleyb2
Copy link

👍

Copy link

ghost commented Jun 14, 2016

nice, thanks

@dtuchs
Copy link

dtuchs commented Mar 9, 2017

thanks!

@IBOUANGA
Copy link

Great job man !

@mythes
Copy link

mythes commented Jul 29, 2017

Thanks!

@mohammad-mahmoodi
Copy link

Thanks!

@JohannesRudolph
Copy link

Here's the same thing in Kotlin for your convenience:


import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.security.SignatureException
import java.util.*
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

object HmacSha1Signature {
  private val HMAC_SHA1_ALGORITHM = "HmacSHA1"

  private fun toHexString(bytes: ByteArray): String {
    val formatter = Formatter()

    for (b in bytes) {
      formatter.format("%02x", b)
    }

    return formatter.toString()
  }

  @Throws(SignatureException::class, NoSuchAlgorithmException::class, InvalidKeyException::class)
  fun calculateRFC2104HMAC(data: String, key: String): String {
    val signingKey = SecretKeySpec(key.toByteArray(), HMAC_SHA1_ALGORITHM)
    val mac = Mac.getInstance(HMAC_SHA1_ALGORITHM)
    mac.init(signingKey)
    return toHexString(mac.doFinal(data.toByteArray()))
  }
}

@r3b311i0n
Copy link

@jsfzoloz
Copy link

jsfzoloz commented Feb 9, 2018

Just FYI, there's a common cryptography bug in the above code. A lot of your key bytes are guessable because you're using UTF8 encoding. That means no non-printable bytes will ever appear in your key and your key entropy is greatly reduced. Always always randomly generate your keys using a SecureRandom and Base64 encode them. Otherwise, only bytes that are printable will be used as key bytes and number of guesses a brute force attacker would have to do is GREATLY reduced!

@jsfzoloz
Copy link

jsfzoloz commented Feb 9, 2018

The correct way to generate a key is:

	public static String generateRandomKey() throws NoSuchAlgorithmException {
		SecureRandom secureRandom = new SecureRandom(SecureRandom.getSeed(32));
		KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA1");
		keyGen.init(secureRandom);
		SecretKey secretKey = keyGen.generateKey();
		String encodedKey = Base64.getEncoder().encodeToString(secretKey.getEncoded());
		return encodedKey;
	}

As an example, the above code can produce 0x6 as a key byte, or 00000110. This binary value cannot be encoded as UTF-8: http://bit.ly/2nOaqFw

@rosdyana
Copy link

rosdyana commented Apr 6, 2018

import java.security.SignatureException;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class HMAC_SHA1 {
	public static String Signature(String xData, String AppKey) throws java.security.SignatureException {
		try {
			final Base64.Encoder encoder = Base64.getEncoder();
			// get an hmac_sha1 key from the raw key bytes
			SecretKeySpec signingKey = new SecretKeySpec(AppKey.getBytes("UTF-8"),"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(xData.getBytes("UTF-8"));
			String result = encoder.encodeToString(rawHmac);
			return result;

		} catch (Exception e) {
			throw new SignatureException("Failed to generate HMAC : "+ e.getMessage());
		}
	}
}

@ivanalexeenko
Copy link

Thank You!

@TiagoSeca
Copy link

thanks

@CoderIdiot
Copy link

nice.

@vijay2982
Copy link

vijay2982 commented Mar 8, 2019

{
final Base64.Encoder encoder = Base64.getEncoder();
SecretKeySpec signingKey;
try {
signingKey = new SecretKeySpec(encoder.encode(key.getBytes("UTF-8")), ""HmacSHA1"");
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
return toHexString(mac.doFinal(encoder.encode(data.getBytes("UTF-8"))));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

@srithar08
Copy link

import java.security.SignatureException;
import java.util.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class HMAC_SHA1 {
	public static String Signature(String xData, String AppKey) throws java.security.SignatureException {
		try {
			final Base64.Encoder encoder = Base64.getEncoder();
			// get an hmac_sha1 key from the raw key bytes
			SecretKeySpec signingKey = new SecretKeySpec(AppKey.getBytes("UTF-8"),"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(xData.getBytes("UTF-8"));
			String result = encoder.encodeToString(rawHmac);
			return result;

		} catch (Exception e) {
			throw new SignatureException("Failed to generate HMAC : "+ e.getMessage());
		}
	}
}

what is xData

@chorandrey
Copy link

for Scala (taken answer above):

  import javax.crypto.Mac
  import javax.crypto.spec.SecretKeySpec
  import org.apache.commons.codec.binary.Base64

  def encryptHMACSHA1(value: String, secretKey: String): String = {
    val signingKey = new SecretKeySpec(secretKey.getBytes, "HmacSHA1")
    val mac = Mac.getInstance("HmacSHA1")
    mac.init(signingKey)
    val rawHmac = mac.doFinal(value.getBytes)
    Base64.encodeBase64String(rawHmac)
  }

@ttraub
Copy link

ttraub commented Feb 17, 2021

Perfect for my needs, thanks so much!

@htteng1976
Copy link

Thanks :)

@clauRamirez
Copy link

Thanks!

@wangschang
Copy link

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment