Webhook events are signed so that the system receiving the event can verify their authenticity. You can also secure webhooks by adding a secret key to the URL, ensuring that your remote system processes only posts from Oracle Commerce Cloud Service.

Webhook POST requests include an HMAC SHA1 signature in the X-Oracle-CC-WebHook-Signature header. This signature is calculated using the secret key to generate a hash of the raw UTF-8 bytes of the body of the post. A base64 encoding is then used to turn the hash into a string. If your secret key has been disclosed or compromised, you can generate a new one.

The following is sample code for generating a HMAC SHA1 signature from a secret key and content. In the case of webhooks, the content String would be the complete, unaltered body of the webhook POST request.

This or similar code can be used to verify that the message was sent by someone with access to the private key (presumably Oracle Commerce Cloud Service), and that the body of the message has not been altered after the fact:

import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * This class provides an example of calculating an HMAC SH1
 * signature in java.
 */
public class CalcHmacSignature {

  /**
   * Calculate an HMAC SHA1 signature.

   *
   * @param pSecretKey the secret key (in string form).
   * @param pContent the content to create a signture for. For
   *  OCCS WebHooks this should be the complete, unmodified body of the post.
   *
   * @return The Base64-encoded HMAC SHA1 signature.
   *
   * @throws java.security.SignatureException if there's a problem
   */
  public static String getSignatureForBytes(String pSecretKey, String pContent)
    throws java.security.SignatureException {

      try {
        // HMAC SHA1 key from the raw key bytes
        SecretKeySpec keySpec = new SecretKeySpec(pSecretKey.getBytes(),
                                                  "HmacSHA1");

        // get the Mac instance for HMAC SHA1
        Mac mac = Mac.getInstance("HmacSHA1");

        // initialize with our key spec
        mac.init(keySpec);

        // generate the signature from the UTF-8 bytes of the content
        byte[] digest = mac.doFinal(pContent.getBytes("UTF-8"));
        // base64-encode the hmac signature... there's a pre-JDK-8 one
        // tucked away in javax.xml.bind. If using Java 8, use the new
        // java.util.Base64 class instead.
        return javax.xml.bind.DatatypeConverter.printBase64Binary(
          digest);
      } catch (Exception e) {
        throw new SignatureException("Failed to generate signature: " +
                                     e.getMessage());
      }
    }

  public static void main(String[] args) throws SignatureException {
    if (args.length != 2) {
      System.out.println("Usage: CalcHmacSignature key content");
      System.out.println();
      System.out.println("  (Note that one shouldn't really have the key ");
      System.out.println("   passed in on the command line.)");
      System.exit(-1);
    }
    System.out.println("Signature: " +  getSignatureForBytes(args[0],
                                                             args[1]));
  }
}

Copyright © 1997, 2016 Oracle and/or its affiliates. All rights reserved. Legal Notices