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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user