Request signature in Java
This article presents a sample implementation of a request signature in Java.
# Dependencies
This example uses the util, net and crypto dependencies from the Java SDK.
# Example
The following simple example implements the algorithm described in the Request signature guide. The most important thing is to calculate HMAC-SHA-256
using any library using the given parameters in the correct order: method
, url
, timestamp
, body
.
The method
parameter should be uppercase and path
should contain only the relative path and query parameters from the URL, not the full URL address. The full URL address should be converted to e.g. /webhook?a=1
.
If the algorithm works correctly, it should generate the same signature as the one given below: 56ac656c7f932c5b775be28949e90af9a2356eae2826539f10ab6526a0eec762
for the following parameters:
-
apiSecret=SECRET
-
method=POST
-
uri=http://demo.example.com/webhook?a=1
-
timestamp=1563276169752
-
body={a:1}
import java.util.Formatter;
import java.util.Map;
import java.net.URI;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
public class Main {
private static final String HMAC_SHA256 = "HmacSHA256";
public static void main(String args[]) throws Exception {
String expectedSignature = "56ac656c7f932c5b775be28949e90af9a2356eae2826539f10ab6526a0eec762";
String signature = generateSignature(
"SECRET",
"POST",
"http://demo.example.com/webhook?a=1",
1563276169752l,
"{\"a\":1}"
);
System.out.println(signature.equals(expectedSignature));
}
private static String toHexString(byte[] bytes) {
Formatter formatter = new Formatter();
for (byte b: bytes) {
formatter.format("%02x", b);
}
return formatter.toString();
}
public static String calculateHMACSHA256(String data, String key) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA256);
Mac mac = Mac.getInstance(HMAC_SHA256);
mac.init(secretKeySpec);
return toHexString(mac.doFinal(data.getBytes()));
}
private static String generateSignature(String secret, String method, String uri, long timestamp) throws Exception {
return generateSignature(secret, method, uri, timestamp, "");
}
private static String generateSignature(String secret, String method, String uri, long timestamp, String bodyString) throws Exception {
String methodUpperCase = method.toUpperCase();
URI url = new URI(uri);
String path = url.getPath();
String query = url.getQuery();
if (!query.isBlank()) {
path = path + "?" + query;
}
String signatureData = methodUpperCase + path + timestamp;
if (bodyString != null) {
signatureData += bodyString;
}
return calculateHMACSHA256(signatureData, secret);
}
}