forked from mars9/crypt
/
key.go
79 lines (63 loc) · 1.73 KB
/
key.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
package crypt
import (
"crypto/sha1"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/scrypt"
)
// Key defines the key derivation function interface.
type Key interface {
// Derive returns the AES key and HMAC-SHA key, for the given password,
// salt combination.
Derive(salt []byte) (aesKey, hmacKey []byte)
// Size returns the key-size. Key-size should either 16, 24, or 32 to
// select AES-128, AES-192, or AES-256.
Size() int
// Reset resets/flushes the key.
Reset()
}
type pbkdf2Key struct {
password []byte
size int
}
// NewPbkdf2Key returns the key derivation function PBKDF2 as defined in
// RFC 2898.
func NewPbkdf2Key(password []byte, size int) Key {
return pbkdf2Key{password: password, size: size}
}
func (k pbkdf2Key) Derive(salt []byte) (aesKey, hmacKey []byte) {
key := pbkdf2.Key(k.password, salt, 4096, 2*k.size, sha1.New)
aesKey = key[:k.size]
hmacKey = key[k.size:]
return aesKey, hmacKey
}
func (k pbkdf2Key) Size() int { return k.size }
func (k pbkdf2Key) Reset() {
for i := range k.password {
k.password[i] = 0
}
}
type scryptKey struct {
password []byte
size int
}
// NewScryptKey returns the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential
// Memory-Hard Functions".
func NewScryptKey(password []byte, size int) Key {
return scryptKey{password: password, size: size}
}
func (k scryptKey) Derive(salt []byte) (aesKey, hmacKey []byte) {
key, err := scrypt.Key(k.password, salt, 16384, 8, 1, 2*k.size)
if err != nil {
panic(err)
}
aesKey = key[:k.size]
hmacKey = key[k.size:]
return aesKey, hmacKey
}
func (k scryptKey) Size() int { return k.size }
func (k scryptKey) Reset() {
for i := range k.password {
k.password[i] = 0
}
}