feat(alerting): HmacSigner for webhook signature

HmacSHA256 signer returning sha256=<lowercase-hex>. 5 unit tests covering
known vector, prefix, hex casing, and different secrets/bodies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-19 20:24:39 +02:00
parent bf178ba141
commit 6f1feaa4b0
2 changed files with 90 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
package com.cameleer.server.app.alerting.notify;
import org.springframework.stereotype.Component;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.HexFormat;
/**
* Computes HMAC-SHA256 webhook signatures.
* <p>
* Output format: {@code sha256=<lowercase hex>}
*/
@Component
public class HmacSigner {
/**
* Signs {@code body} with {@code secret} using HmacSHA256.
*
* @param secret plain-text secret (UTF-8 encoded)
* @param body request body bytes to sign
* @return {@code "sha256=" + hex(hmac)}
*/
public String sign(String secret, byte[] body) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] digest = mac.doFinal(body);
return "sha256=" + HexFormat.of().formatHex(digest);
} catch (Exception e) {
throw new IllegalStateException("HMAC signing failed", e);
}
}
}