Add HMAC with encoding options
This commit is contained in:
parent
bdc172df39
commit
12e12c9536
3 changed files with 175 additions and 1 deletions
|
|
@ -37,6 +37,12 @@ var HashTypes = map[string]crypto.Hash{
|
|||
"BLAKE2b_512": crypto.BLAKE2b_512,
|
||||
}
|
||||
|
||||
type hmacOption struct {
|
||||
keyEncoding string // base64 | hex
|
||||
valueEncoding string // base64 | hex
|
||||
outputEncoding string // base64 | hex
|
||||
}
|
||||
|
||||
// Hash string
|
||||
func Hash(hash crypto.Hash, value string) (string, error) {
|
||||
h := hash.New()
|
||||
|
|
@ -62,6 +68,67 @@ func Hmac(hash crypto.Hash, value string, key string, encoding ...string) (strin
|
|||
return fmt.Sprintf("%x", mac.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// HmacWith the Keyed-Hash Message Authentication Code (HMAC)
|
||||
func HmacWith(option *hmacOption, hash crypto.Hash, value string, key string) (string, error) {
|
||||
var k []byte
|
||||
var v []byte
|
||||
var err error
|
||||
if option == nil {
|
||||
option = &hmacOption{}
|
||||
}
|
||||
|
||||
switch option.keyEncoding {
|
||||
case "base64":
|
||||
k, err = base64.StdEncoding.DecodeString(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
|
||||
case "hex":
|
||||
k, err = hex.DecodeString(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
k = []byte(key)
|
||||
}
|
||||
|
||||
switch option.valueEncoding {
|
||||
case "base64":
|
||||
v, err = base64.StdEncoding.DecodeString(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
case "hex":
|
||||
v, err = hex.DecodeString(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
default:
|
||||
v = []byte(value)
|
||||
}
|
||||
|
||||
mac := hmac.New(hash.New, k)
|
||||
_, err = mac.Write(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch option.outputEncoding {
|
||||
case "base64":
|
||||
return base64.StdEncoding.EncodeToString(mac.Sum(nil)), nil
|
||||
case "hex":
|
||||
return fmt.Sprintf("%x", mac.Sum(nil)), nil
|
||||
default:
|
||||
return fmt.Sprintf("%x", mac.Sum(nil)), nil
|
||||
}
|
||||
}
|
||||
|
||||
// RSA2Sign RSA2 Sign
|
||||
func RSA2Sign(prikey string, hash crypto.Hash, value string, encoding ...string) (string, error) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -150,3 +153,72 @@ func TestRSA2SignProcessBase64(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, true, valid)
|
||||
}
|
||||
|
||||
// ProcessHmacWith tests
|
||||
|
||||
func TestHmacWith(t *testing.T) {
|
||||
keyhex := hex.EncodeToString([]byte("key"))
|
||||
valuehex := hex.EncodeToString([]byte("value"))
|
||||
keybase64 := base64.StdEncoding.EncodeToString([]byte("key"))
|
||||
valuebase64 := base64.StdEncoding.EncodeToString([]byte("value"))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
option *hmacOption
|
||||
hash crypto.Hash
|
||||
value string
|
||||
key string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Test with hex encoding",
|
||||
option: &hmacOption{
|
||||
keyEncoding: "hex",
|
||||
valueEncoding: "hex",
|
||||
outputEncoding: "hex",
|
||||
},
|
||||
hash: crypto.SHA256,
|
||||
value: valuehex,
|
||||
key: keyhex,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Test with base64 encoding",
|
||||
option: &hmacOption{
|
||||
keyEncoding: "base64",
|
||||
valueEncoding: "base64",
|
||||
outputEncoding: "base64",
|
||||
},
|
||||
hash: crypto.SHA256,
|
||||
value: valuebase64,
|
||||
key: keybase64,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Test with default encoding",
|
||||
option: &hmacOption{},
|
||||
hash: crypto.SHA256,
|
||||
value: "value",
|
||||
key: "key",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Test with nil option",
|
||||
option: nil,
|
||||
hash: crypto.SHA256,
|
||||
value: "value",
|
||||
key: "key",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := HmacWith(tt.option, tt.hash, tt.value, tt.key)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("HmacWith() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ func init() {
|
|||
process.Alias("yao.crypto.hash", "crypto.Hash")
|
||||
process.Alias("yao.crypto.hmac", "crypto.Hmac")
|
||||
|
||||
process.Register("crypto.hmacwith", ProcessHmacWith)
|
||||
process.Register("crypto.rsa2sign", ProcessRsa2Sign)
|
||||
process.Register("crypto.rsa2verify", ProcessRsa2Verify)
|
||||
process.Register("crypto.aes256encrypt", ProcessAes256Encrypt)
|
||||
|
|
@ -49,7 +50,7 @@ func ProcessHash(process *process.Process) interface{} {
|
|||
// Args[0] string: the hash function name. MD4/MD5/SHA1/SHA224/SHA256/SHA384/SHA512/MD5SHA1/RIPEMD160/SHA3_224/SHA3_256/SHA3_384/SHA3_512/SHA512_224/SHA512_256/BLAKE2s_256/BLAKE2b_256/BLAKE2b_384/BLAKE2b_512
|
||||
// Args[1] string: value
|
||||
// Args[2] string: key
|
||||
// Args[3] string: base64
|
||||
// Args[3] string: base64 (optional)
|
||||
func ProcessHmac(process *process.Process) interface{} {
|
||||
process.ValidateArgNums(3)
|
||||
typ := process.ArgsString(0)
|
||||
|
|
@ -73,6 +74,40 @@ func ProcessHmac(process *process.Process) interface{} {
|
|||
return res
|
||||
}
|
||||
|
||||
// ProcessHmacWith yao.crypto.hmac Crypto the Keyed-Hash Message Authentication Code (HMAC) Hash
|
||||
// Args[0] map: option {"key": "base64", "value": "base64", "output": "base64"} // hex/base64
|
||||
// Args[1] string: value
|
||||
// Args[2] string: key
|
||||
func ProcessHmacWith(process *process.Process) interface{} {
|
||||
process.ValidateArgNums(3)
|
||||
option := process.ArgsMap(0)
|
||||
value := process.ArgsString(1)
|
||||
key := process.ArgsString(2)
|
||||
typ := "SHA256"
|
||||
o := &hmacOption{}
|
||||
if v, has := option["key"].(string); has {
|
||||
o.keyEncoding = v
|
||||
}
|
||||
if v, has := option["value"].(string); has {
|
||||
o.valueEncoding = v
|
||||
}
|
||||
if v, has := option["output"].(string); has {
|
||||
o.outputEncoding = v
|
||||
}
|
||||
if v, has := option["type"].(string); has {
|
||||
typ = v
|
||||
}
|
||||
h, has := HashTypes[typ]
|
||||
if !has {
|
||||
exception.New("%s does not support", 400, typ).Throw()
|
||||
}
|
||||
res, err := HmacWith(o, h, value, key)
|
||||
if err != nil {
|
||||
exception.New("%s error: %s value: %s", 400, typ, err, value).Throw()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// ProcessRsa2Sign crypto.rsa2sign
|
||||
// Args[0] string: the private key
|
||||
// Args[1] string: the hash function name. MD4/MD5/SHA1/SHA224/SHA256/SHA384/SHA512/MD5SHA1/RIPEMD160/SHA3_224/SHA3_256/SHA3_384/SHA3_512/SHA512_224/SHA512_256/BLAKE2s_256/BLAKE2b_256/BLAKE2b_384/BLAKE2b_512
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue