67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
package signature
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Request struct {
|
|
Algorithm string `json:"algorithm"`
|
|
Data string `json:"data"`
|
|
Secret string `json:"secret,omitempty"`
|
|
Encoding string `json:"encoding,omitempty"`
|
|
}
|
|
|
|
type Result struct {
|
|
Algorithm string `json:"algorithm"`
|
|
Encoding string `json:"encoding"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
func Calculate(request Request) (Result, error) {
|
|
algorithm := strings.ToLower(strings.TrimSpace(request.Algorithm))
|
|
encoding := strings.ToLower(strings.TrimSpace(request.Encoding))
|
|
if encoding == "" {
|
|
encoding = "hex"
|
|
}
|
|
|
|
var digest []byte
|
|
switch algorithm {
|
|
case "sha256":
|
|
sum := sha256.Sum256([]byte(request.Data))
|
|
digest = sum[:]
|
|
case "hmac-sha256":
|
|
mac := hmac.New(sha256.New, []byte(request.Secret))
|
|
_, _ = mac.Write([]byte(request.Data))
|
|
digest = mac.Sum(nil)
|
|
default:
|
|
return Result{}, fmt.Errorf("unsupported signature algorithm %q", request.Algorithm)
|
|
}
|
|
|
|
value, err := encode(digest, encoding)
|
|
if err != nil {
|
|
return Result{}, err
|
|
}
|
|
|
|
return Result{
|
|
Algorithm: algorithm,
|
|
Encoding: encoding,
|
|
Value: value,
|
|
}, nil
|
|
}
|
|
|
|
func encode(bytes []byte, encoding string) (string, error) {
|
|
switch encoding {
|
|
case "hex":
|
|
return hex.EncodeToString(bytes), nil
|
|
case "base64":
|
|
return base64.StdEncoding.EncodeToString(bytes), nil
|
|
default:
|
|
return "", fmt.Errorf("unsupported signature encoding %q", encoding)
|
|
}
|
|
}
|