-
Notifications
You must be signed in to change notification settings - Fork 1
/
signature.go
81 lines (72 loc) · 1.82 KB
/
signature.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package signature_header
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"encoding/base64"
"fmt"
"strings"
)
// Example:
//
// privateKey, err := signature_header.PrivateKeyFromBytes(privateKeyBytes)
// date := signature_header.Date()
// digest := signature_header.Digest(crypto.SHA256, message)
// signature, err := signature_header.Signature{
// PrivateKey: privateKey,
// Algorithm: crypto.SHA256,
// Date: date,
// Digest: digest,
// Host: "yodangang.express",
// Path: "/users/9iffvxhojp/inbox",
// KeyID: "https://snippet.cloudmt.co.kr/@juunini#main-key",
// }.String()
type Signature struct {
PrivateKey *rsa.PrivateKey
Algorithm crypto.Hash
Date string
Digest string
Host string
Path string
KeyID string
}
func (s Signature) String() (string, error) {
message := fmt.Sprintf(`(request-target): post %s
date: %s
host: %s
digest: %s`,
s.Path,
s.Date,
s.Host,
s.Digest,
)
signed, err := rsa.SignPKCS1v15(
rand.Reader,
s.PrivateKey,
s.Algorithm,
hashing(s.Algorithm, []byte(message)),
)
if err != nil {
return "", err
}
signature := base64.StdEncoding.EncodeToString(signed)
return strings.Join([]string{
fmt.Sprintf(`keyId="%s"`, s.KeyID),
fmt.Sprintf(`algorithm="rsa-%s"`, strings.Replace(strings.ToLower(s.Algorithm.String()), "-", "", 1)),
`headers="(request-target) date host digest"`,
fmt.Sprintf(`signature="%s"`, signature),
}, ","), nil
}
func ParseSignature(signatureStr string) map[string]string {
parsedSignature := map[string]string{}
for _, param := range strings.Split(strings.Replace(signatureStr, "Signature ", "", 1), ",") {
split := strings.Split(param, "=")
key := split[0]
value := strings.ReplaceAll(
strings.Join(split[1:], "="),
`"`, "",
)
parsedSignature[key] = value
}
return parsedSignature
}