Skip to main content

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:
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:
java verifier.java
The program will print true if the signature is valid, false otherwise.

Next Steps