-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsign.go
58 lines (48 loc) · 1.46 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
57
58
// @author: Brian Wojtczak
// @copyright: 2024 by Brian Wojtczak
// @license: BSD-style license found in the LICENSE file
package altcha
import (
"crypto/hmac"
"encoding/base64"
"hash"
)
// Sign generates a signature for the given text.
func Sign(algo Algorithm, text string) string {
secret, _ := GetSecrets()
return sign(algo, text, secret)
}
func sign(algo Algorithm, text, secret string) string {
if len(secret) == 0 {
panic("secret not provided to signing function")
}
newHasher := func() (hasher hash.Hash) {
hasher, _ = getHasher(algo)
return hasher
}
signer := hmac.New(newHasher, []byte(secret))
signer.Write([]byte(text))
// The official server implementation example uses hex encoding.
// However, as the client doesn't read the signature, this can be changed
// without affecting compatibility.
// This implementation uses base64 encoding produces shorter signatures.
return base64.RawURLEncoding.EncodeToString(signer.Sum(nil))
}
// VerifySignature checks if the given signature is valid for the given text.
func VerifySignature(algo Algorithm, text string, signature string) (valid bool) {
if len(signature) == 0 {
return false
}
current, previous := GetSecrets()
// Check using the current secret
validSignature := sign(algo, text, current)
if signature == validSignature {
return true
}
// Check using the previous secret
validSignature = sign(algo, text, previous)
if signature == validSignature {
return true
}
return false
}