-
Notifications
You must be signed in to change notification settings - Fork 0
/
keygen.go
72 lines (59 loc) · 1.32 KB
/
keygen.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
package crypto
import (
"bytes"
"crypto/aes"
"crypto/sha1"
"crypto/sha256"
"crypto/subtle"
"hash"
"golang.org/x/crypto/pbkdf2"
)
const (
keySize = 64
keyIter = 65536
)
// hash generator
type HashFunc func() hash.Hash
// Digest algorithms
type Digest int
const (
SHA1 Digest = iota
SHA256
invalidDigest
)
// hash functions
var hashFuncs = []HashFunc{
sha1.New,
sha256.New,
}
// Obtain the digest hash function
func (d Digest) Func() HashFunc {
if d >= SHA1 && d < invalidDigest {
return hashFuncs[int(d)]
} else {
panic("Invalid digest")
}
}
// Pad an AES block
func PKCS5Pad(in []byte) []byte {
pad := aes.BlockSize - (len(in) % aes.BlockSize)
return append(in, bytes.Repeat([]byte{byte(pad)}, pad)...)
}
// Unpad an AES block
func PKCS5Unpad(in []byte) []byte {
l := len(in)
p := int(in[l-1])
return in[:l-p]
}
// Generate a Rails-compatible key
func GenerateKey(secret, salt string, digest Digest) []byte {
return GenerateKeyWithOptions(secret, salt, keyIter, keySize, digest.Func())
}
// Generate a key with options
func GenerateKeyWithOptions(secret, salt string, iter, size int, hgen HashFunc) []byte {
return pbkdf2.Key([]byte(secret), []byte(salt), iter, size, hgen)
}
// Compare strings in constant time
func SecureCompare(a, b string) bool {
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}