-
Notifications
You must be signed in to change notification settings - Fork 25
/
kdf_pcrypt.go
93 lines (74 loc) · 2.12 KB
/
kdf_pcrypt.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
82
83
84
85
86
87
88
89
90
91
92
93
package ssh
import (
"bytes"
"errors"
"encoding/binary"
"github.com/deatil/go-cryptobin/kdf/bcrypt_pbkdf"
)
var (
pcryptName = "pcrypt"
)
// pcrypt 数据
type pcryptParams struct {}
func parseBcryptKdfOpts(kdfOpts string) ([]byte, uint32, error) {
// Read kdf options.
buf := bytes.NewReader([]byte(kdfOpts))
var saltLength uint32
if err := binary.Read(buf, binary.BigEndian, &saltLength); err != nil {
return nil, 0, errors.New("cannot decode encrypted private keys: bad format")
}
salt := make([]byte, saltLength)
if err := binary.Read(buf, binary.BigEndian, &salt); err != nil {
return nil, 0, errors.New("cannot decode encrypted private keys: bad format")
}
var rounds uint32
if err := binary.Read(buf, binary.BigEndian, &rounds); err != nil {
return nil, 0, errors.New("cannot decode encrypted private keys: bad format")
}
return salt, rounds, nil
}
func (this pcryptParams) DeriveKey(password []byte, kdfOpts string, size int) (key []byte, err error) {
salt, rounds, err := parseBcryptKdfOpts(kdfOpts)
if err != nil {
return nil, err
}
return bcrypt_pbkdf.Key(
password, salt,
int(rounds), size,
)
}
// PcryptOpts 设置
type PcryptOpts struct {
SaltSize int
Rounds int
}
func (this PcryptOpts) DeriveKey(password []byte, size int) (key []byte, params string, err error) {
salt, err := genRandom(this.SaltSize)
if err != nil {
return nil, "", err
}
key, err = bcrypt_pbkdf.Key(
password, salt,
this.Rounds, size,
)
if err != nil {
return nil, "", err
}
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, uint32(this.SaltSize))
binary.Write(buf, binary.BigEndian, salt)
binary.Write(buf, binary.BigEndian, uint32(this.Rounds))
params = buf.String()
return key, params, nil
}
func (this PcryptOpts) GetSaltSize() int {
return this.SaltSize
}
func (this PcryptOpts) Name() string {
return pcryptName
}
func init() {
AddKDF(pcryptName, func() KDFParameters {
return new(pcryptParams)
})
}