# Request signature in Java

This article presents a sample implementation of a [request signature](../../developer-resources/security/request-signature.md) in Java.

<a id="dependencies">

## Dependencies

This example uses the [util](https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/package-summary.html), [net](https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/net/package-summary.html) and [crypto](https://docs.oracle.com/en/java/javase/18/docs/api/java.base/javax/crypto/package-summary.html) dependencies from the Java SDK.

<a id="example">

## Example

The following simple example implements the algorithm described in the [Request signature](../../developer-resources/security/request-signature.md) 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}`

```java
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);
	}
}
```

---

Full index of the Cloud Services documentation: [llms.txt](../../../llms.txt)
