-
Notifications
You must be signed in to change notification settings - Fork 0
/
sign.go
56 lines (50 loc) · 1.31 KB
/
sign.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package crypto
import (
"crypto/hmac"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
)
var ErrSignatureNotValid = fmt.Errorf("Signature not valid")
// Sign data using HMAC
func Sign(key []byte, digest Digest, data []byte) string {
mac := hmac.New(digest.Func(), key)
mac.Write(data)
return hex.EncodeToString(mac.Sum(nil))
}
// Verify a signature
func Verify(key []byte, digest Digest, sig string, data []byte) bool {
b, err := hex.DecodeString(sig)
if err != nil {
return false
}
mac := hmac.New(digest.Func(), key)
mac.Write(data)
return hmac.Equal(b, mac.Sum(nil))
}
// Produce a serialized, base64-encoded message and its signature
func SignMessage(key []byte, digest Digest, message interface{}) (string, string, error) {
m, err := json.Marshal(message)
if err != nil {
return "", "", err
}
b := base64.StdEncoding.EncodeToString(m)
s := Sign(key, digest, []byte(b))
return b, s, nil
}
// Validate a message signature and, if valid, unmarshal the message
func VerifyMessage(key []byte, digest Digest, sig string, message interface{}, data string) error {
if !Verify(key, digest, sig, []byte(data)) {
return ErrSignatureNotValid
}
m, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return err
}
err = json.Unmarshal(m, message)
if err != nil {
return err
}
return nil
}