Notification Signature
Notification Signature
Verify a notification signature
All notifications/callbacks to the merchant should be signed using the HMAC-SHA256 algorithm, and the contents of the signature should be included in the "Liquido-Signature" header. This header should have the signature timestamp in seconds and the hash function used, such as below:
A merchant can verify the signature with the following steps:
- Get the payload as a raw request body string
- Set the signature content as:
payload={{payload}},timestamp={{current_timestamp_in_seconds}}
- Set the signature secret to the client secret used in the OAuth Token
signature = HmacSHA256(content, secret)
Example of HMAC signature verification in Java
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.codec.binary.Hex;
public class HmacSignUtils {
private static final String HEADER_FORMAT_STRING = "algorithm=%s,timestamp=%s,signature=%s";
private static final String CONTENT_FORMAT_STRING = "payload=%s,timestamp=%s";
public static final String ALGORITHM = "HmacSHA256";
public static final String SIGNATURE_HEADER_KEY = "Liquido-Signature";
public boolean verifySignature(
final String signature,
final String payload,
final String timestamp,
final String secret
) throws NoSuchAlgorithmException, InvalidKeyException {
final String content = String.format(CONTENT_FORMAT_STRING, payload, timestamp);
return signature.equals(calculateSignature(content, secret));
}
private static String calculateSignature(final String content, final String secret)
throws NoSuchAlgorithmException, InvalidKeyException {
final Mac sha256Hmac = Mac.getInstance(ALGORITHM);
final SecretKeySpec keySpec =
new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), ALGORITHM);
sha256Hmac.init(keySpec);
final byte[] digest = sha256Hmac.doFinal(content.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(digest);
}
}