You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
34 lines
926 B
34 lines
926 B
package security |
|
|
|
import ( |
|
"crypto/hmac" |
|
"crypto/sha256" |
|
"encoding/hex" |
|
"log/slog" |
|
"strings" |
|
) |
|
|
|
// VerifyHMACSHA256 checks a hex HMAC-SHA256 signature over the raw body. |
|
// |
|
// If no secret is configured we skip verification (dev convenience) but log a |
|
// warning, so it is never silently insecure where a secret IS set. |
|
func VerifyHMACSHA256(secret string, body []byte, signature string) bool { |
|
if secret == "" { |
|
slog.Warn("signature secret not configured — skipping verification") |
|
return true |
|
} |
|
if signature == "" { |
|
return false |
|
} |
|
|
|
signature = strings.TrimSpace(signature) |
|
// Some providers prefix the digest, e.g. "sha256=abc...". |
|
if strings.HasPrefix(strings.ToLower(signature), "sha256=") { |
|
signature = signature[len("sha256="):] |
|
} |
|
|
|
mac := hmac.New(sha256.New, []byte(secret)) |
|
mac.Write(body) |
|
expected := hex.EncodeToString(mac.Sum(nil)) |
|
return hmac.Equal([]byte(expected), []byte(signature)) |
|
}
|
|
|