> ## Documentation Index
> Fetch the complete documentation index at: https://developer.utgl.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify webhook signature with Java

## Overview

This tutorial shows you how to verify the signature of incoming webhooks from the Issuing API using Java. This ensures that webhook requests are authentic and come from our servers.

## Complete Code

Here is the complete `WebhookSignVerifier` class:

```java theme={null}
package com.example;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class WebhookSignVerifier {
  
  public static boolean verify(String publicKeyPEM, String signature, String body) {
    try {
      publicKeyPEM = publicKeyPEM
          .replace("-----BEGIN PUBLIC KEY-----", "")
          .replace("-----END PUBLIC KEY-----", "")
          .replaceAll("\\s+", "");
      byte[] keyBytes = Base64.getDecoder().decode(publicKeyPEM);
      X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PublicKey publicKey = keyFactory.generatePublic(spec);

      Signature sig = Signature.getInstance("SHA256withRSA");
      sig.initVerify(publicKey);
      sig.update(body.getBytes(StandardCharsets.UTF_8));

      byte[] signatureBytes = Base64.getDecoder().decode(signature);
      return sig.verify(signatureBytes);
    } catch (Exception e) {
      System.err.println(e.getMessage());
      return false;
    }
  }

  public static void main(String[] args) {
    
    String publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" +
        "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA24Ee/VaDjmmz0WFeP2Ff\n" +
        "Ish3L2aYiyaHdnphrUiBPRo5ipnLBQkEqnuqHaVakAtNUTJdpwqNgkni4orF4U/d\n" +
        "wsc+l8nd7AuJXs9TxnpDVI3YU1IerwTfs5ORmGewpr9ebnkKY8bcs69kIxZy+4ra\n" +
        "vrk/HBsB317N0LuaoxR7yARORoPuShcwWCc1VlxRKIaZgGHDF3ab145hhYalE/it\n" +
        "GOA2WUjtvM0dogRq6qMKpG0jfMGEK9wdxFGknTr5yTJBuuJvH8x5Oro0fM0vTKMy\n" +
        "qEEXzng/OeVovKZOo7DAQEJfF55O3NqDx+7l1Xfa5BQHyXkqREdSAwZz/7wX/I33\n" +
        "MrLjqAZD1pSlglXwjM0tz6HW7Et7PuV2u9vhOFMLKe9toUTZA46pebcSfPmUoXYF\n" +
        "PDVxnIi5A9bY59Xs7FxDLOPUcafpRTdj/WUliu9btXxfKdWzPuRRNB9mnAymsBj9\n" +
        "vNZmWvpB5bKg29mvI8rP8oc2gs09qYUl1UnIBI2p1GxS+ABbI8eQSenbOxi3u1tR\n" +
        "FZ4QKP1KECJ8VS+cQ+dKQl4gptqRpLhxkpfrZY81vO9IzNov4x4eOdiffhdCg/po\n" +
        "W4ClrhdBVZMcdImmhG9H4W1g5iKHvDWwieOCb+Q36X6N5gqQ/MPf6lX07e1v4vLu\n" +
        "EWljDKDXsmC4+7xu4LTPJE8CAwEAAQ==\n" +
        "-----END PUBLIC KEY-----";
    
    // from header
    String signature = "paste your signature here from header x-access-signature";
    
    // {"id":"dabca946-6ddb-4dca-bc31-ced69f1f5fe7","event":"account.transaction.created","data":{}}
    String webhookBody = "paste your json string here";
    
    boolean isValid = verify(publicKeyPem, signature, webhookBody);
    System.out.println(isValid); // True if signature is valid, False otherwise
  }
}
```

## Step 1: Paste the public key

The `publicKeyPem` variable contains the Issuing API Webhook public key. This is used to verify that webhook requests come from our servers.

## Step 2: Get the signature from header

Get `x-access-signature` from the header of the webhook request and assign it to the `signature` variable.

## Step 3: Get the webhook body in JSON string

Get the raw webhook request body as a JSON string and assign it to the `webhookBody` variable.

## Step 4: Run the main function

Run the verifier to check if the webhook signature is valid:

```bash theme={null}
java verifier.java
```

The program will print `true` if the signature is valid, `false` otherwise.

## Next Steps

* Learn more about [Webhooks](/issuing/guides/webhooks-1)
* Explore [Webhook Events](/issuing/guides/webhook-events-1)
* See the Node.js version: [Verify webhook signature with node.js](/tutorials/verify-webhook-nodejs)
