Webhook validation in Java

Hi Team, I am doing a webhook function on Java. Here is the code:

  private String fireBlocksPublicKey = "-----BEGIN PUBLIC KEY-----\n" +
          "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+fZuC+0vDYTf8fYnCN6\n" +
          "71iHg98lPHBmafmqZqb+TUexn9sH6qNIBZ5SgYFxFK6dYXIuJ5uoORzihREvZVZP\n" +
          "8DphdeKOMUrMr6b+Cchb2qS8qz8WS7xtyLU9GnBn6M5mWfjkjQr1jbilH15Zvcpz\n" +
          "ECC8aPUAy2EbHpnr10if2IHkIAWLYD+0khpCjpWtsfuX+LxqzlqQVW9xc6z7tshK\n" +
          "eCSEa6Oh8+ia7Zlu0b+2xmy2Arb6xGl+s+Rnof4lsq9tZS6f03huc+XVTmd6H2We\n" +
          "WxFMfGyDCX2akEg2aAvx7231/6S0vBFGiX0C+3GbXlieHDplLGoODHUt5hxbPJnK\n" +
          "IwIDAQAB\n" +
          "-----END PUBLIC KEY-----";

  @Override
  public ResultVO<Boolean> webhook(
    @RequestHeader(value = "fireblocks-signature") String fireblocksSignature,
    FireBlocksWebHookDTO dto
  ) throws
    NoSuchAlgorithmException,
    InvalidKeySpecException,
    InvalidKeyException,
    SignatureException,
    JsonProcessingException
  {

    //Prepare the public key
    String pubKeyPEM = fireBlocksPublicKey
      .replace("-----BEGIN PUBLIC KEY-----\n", "")
      .replace("-----END PUBLIC KEY-----", "");

    byte[] encodedPublicKey = Base64.decode(pubKeyPEM);
    X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedPublicKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey publicKey = kf.generatePublic(spec);
    

    Signature sig = Signature.getInstance("SHA512withRSA");
    sig.initVerify(publicKey);

    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(dto);

    try {
      //decode the signature
      byte[] decoded_signature = Base64.decode(fireblocksSignature);
      int signature_length = decoded_signature.length;
      System.out.println("Signature length in bytes: " + signature_length);


    sig.update(json.getBytes(StandardCharsets.UTF_8));
    final boolean valid = sig.verify(decoded_signature);

      System.out.println("valid >>>>>>" + valid);
    } catch (Exception e) {
      e.printStackTrace(); // 打印异常堆栈信息
      System.out.println("Exception message: " + e.getMessage()); // 打印异常消息
    }

I confirm:1.use the right publicKey of SandBox. 2.The json used to validate the signature is same as the one from fireblocks.

The problem is I can receive the information from fireBlocks but the valid is always false.

Could someone help me with this?

Hi @Zachary ,

My name is Alon and I am part of the Solutions Engineering team at Fireblocks.

Concerning your issue, I believe that the issue is due to the way your DTO is written as string.
I suggest to print it out and compare it to the actual sent payload and verify that the both are the same and that there aren’t any additional characters or missing fields.

Also, please make sure you’re using the relevant public key, the one you wrote in your code is the Sandbox’s public key, if you’re using the Sandbox that’s correct, otherwise you’ll need the production public key that can be found here

Thanks,
Alon