tpl/crypto: Add optional encoding arg to hmac function

Closes #9709
This commit is contained in:
Joe Mooring 2022-03-23 09:48:34 -07:00 committed by Bjørn Erik Pedersen
parent a461e9d01a
commit 94e8a90769
3 changed files with 49 additions and 27 deletions

View file

@ -1,7 +1,7 @@
--- ---
title: hmac title: hmac
linktitle: hmac linktitle: hmac
description: Compute the cryptographic checksum of a message. description: Returns a cryptographic hash that uses a key to sign a message.
date: 2020-05-29 date: 2020-05-29
publishdate: 2020-05-29 publishdate: 2020-05-29
lastmod: 2020-05-29 lastmod: 2020-05-29
@ -10,24 +10,25 @@ menu:
docs: docs:
parent: "functions" parent: "functions"
keywords: [hmac,checksum] keywords: [hmac,checksum]
signature: ["hmac HASH_TYPE KEY MESSAGE"] signature: ["crypto.HMAC HASH_TYPE KEY MESSAGE [ENCODING]","hmac HASH_TYPE KEY MESSAGE [ENCODING]" ]
workson: [] workson: []
hugoversion: hugoversion:
relatedfuncs: [hmac] relatedfuncs: [hmac]
deprecated: false deprecated: false
aliases: [hmac] aliases: []
--- ---
`hmac` returns a cryptographic hash that uses a key to sign a message. Set the `HASH_TYPE` argument to `md5`, `sha1`, `sha256`, or `sha512`.
Set the optional `ENCODING` argument to either `hex` (default) or `binary`.
```go-html-template
{{ hmac "sha256" "Secret key" "Secret message" }}
5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84
{{ hmac "sha256" "Secret key" "Secret message" "hex" }}
5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84
{{ hmac "sha256" "Secret key" "Secret message" "binary" | base64Encode }}
XM60kfRfixVOIPOwow7Tpv8wJ9Nz+Fx4/+iYMYCwPIQ=
``` ```
{{ hmac "sha256" "Secret key" "Hello world, gophers!"}},
<!-- returns the string "b6d11b6c53830b9d87036272ca9fe9d19306b8f9d8aa07b15da27d89e6e34f40"
```
Supported hash functions:
* md5
* sha1
* sha256
* sha512

View file

@ -69,7 +69,7 @@ func (ns *Namespace) SHA256(in any) (string, error) {
} }
// HMAC returns a cryptographic hash that uses a key to sign a message. // HMAC returns a cryptographic hash that uses a key to sign a message.
func (ns *Namespace) HMAC(h any, k any, m any) (string, error) { func (ns *Namespace) HMAC(h any, k any, m any, e ...any) (string, error) {
ha, err := cast.ToStringE(h) ha, err := cast.ToStringE(h)
if err != nil { if err != nil {
return "", err return "", err
@ -105,5 +105,21 @@ func (ns *Namespace) HMAC(h any, k any, m any) (string, error) {
return "", err return "", err
} }
return hex.EncodeToString(mac.Sum(nil)[:]), nil var encoding = "hex"
if len(e) > 0 && e[0] != nil {
encoding, err = cast.ToStringE(e[0])
if err != nil {
return "", err
}
}
switch encoding {
case "binary":
return string(mac.Sum(nil)[:]), nil
case "hex":
return hex.EncodeToString(mac.Sum(nil)[:]), nil
default:
return "", fmt.Errorf("%q is not a supported encoding method", encoding)
}
} }

View file

@ -107,20 +107,25 @@ func TestHMAC(t *testing.T) {
ns := New() ns := New()
for i, test := range []struct { for i, test := range []struct {
hash any hash any
key any key any
msg any msg any
expect any encoding any
expect any
}{ }{
{"md5", "Secret key", "Hello world, gophers!", "36eb69b6bf2de96b6856fdee8bf89754"}, {"md5", "Secret key", "Hello world, gophers!", nil, "36eb69b6bf2de96b6856fdee8bf89754"},
{"sha1", "Secret key", "Hello world, gophers!", "84a76647de6cd47ac6ae4258e3753f711172ce68"}, {"sha1", "Secret key", "Hello world, gophers!", nil, "84a76647de6cd47ac6ae4258e3753f711172ce68"},
{"sha256", "Secret key", "Hello world, gophers!", "b6d11b6c53830b9d87036272ca9fe9d19306b8f9d8aa07b15da27d89e6e34f40"}, {"sha256", "Secret key", "Hello world, gophers!", nil, "b6d11b6c53830b9d87036272ca9fe9d19306b8f9d8aa07b15da27d89e6e34f40"},
{"sha512", "Secret key", "Hello world, gophers!", "dc3e586cd936865e2abc4c12665e9cc568b2dad714df3c9037cbea159d036cfc4209da9e3fcd30887ff441056941966899f6fb7eec9646ff9ddb592595a8eb7f"}, {"sha512", "Secret key", "Hello world, gophers!", nil, "dc3e586cd936865e2abc4c12665e9cc568b2dad714df3c9037cbea159d036cfc4209da9e3fcd30887ff441056941966899f6fb7eec9646ff9ddb592595a8eb7f"},
{"", t, "", false}, {"md5", "Secret key", "Hello world, gophers!", "hex", "36eb69b6bf2de96b6856fdee8bf89754"},
{"md5", "Secret key", "Hello world, gophers!", "binary", "6\xebi\xb6\xbf-\xe9khV\xfd\xee\x8b\xf8\x97T"},
{"md5", "Secret key", "Hello world, gophers!", "foo", false},
{"md5", "Secret key", "Hello world, gophers!", "", false},
{"", t, "", nil, false},
} { } {
errMsg := qt.Commentf("[%d] %v, %v, %v", i, test.hash, test.key, test.msg) errMsg := qt.Commentf("[%d] %v, %v, %v, %v", i, test.hash, test.key, test.msg, test.encoding)
result, err := ns.HMAC(test.hash, test.key, test.msg) result, err := ns.HMAC(test.hash, test.key, test.msg, test.encoding)
if b, ok := test.expect.(bool); ok && !b { if b, ok := test.expect.(bool); ok && !b {
c.Assert(err, qt.Not(qt.IsNil), errMsg) c.Assert(err, qt.Not(qt.IsNil), errMsg)