52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package sign
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type HMACSign struct {
|
|
SecretKey []byte
|
|
}
|
|
|
|
func (s HMACSign) Sign(data string, expire int64) string {
|
|
h := hmac.New(sha256.New, s.SecretKey)
|
|
expireTimeStamp := strconv.FormatInt(expire, 10)
|
|
_, err := io.WriteString(h, data+":"+expireTimeStamp)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
return base64.URLEncoding.EncodeToString(h.Sum(nil)) + ":" + expireTimeStamp
|
|
}
|
|
|
|
func (s HMACSign) Verify(data, sign string) error {
|
|
signSlice := strings.Split(sign, ":")
|
|
// check whether contains expire time
|
|
if signSlice[len(signSlice)-1] == "" {
|
|
return ErrExpireMissing
|
|
}
|
|
// check whether expire time is expired
|
|
expires, err := strconv.ParseInt(signSlice[len(signSlice)-1], 10, 64)
|
|
if err != nil {
|
|
return ErrExpireInvalid
|
|
}
|
|
// if expire time is expired, return error
|
|
if expires < time.Now().Unix() && expires != 0 {
|
|
return ErrSignExpired
|
|
}
|
|
// verify sign
|
|
if s.Sign(data, expires) != sign {
|
|
return ErrSignInvalid
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func NewHMACSign(secret []byte) Sign {
|
|
return HMACSign{SecretKey: secret}
|
|
}
|