@@ -10,11 +10,36 @@ import (
1010 "crypto/subtle"
1111 "encoding/base64"
1212
13- "golang.org/x/crypto /argon2"
13+ "github.com/deatil/go-cryptobin/kdf /argon2"
1414)
1515
16- // 配置
17- type Opt struct {
16+ // Argon2 Type enum
17+ type Argon2Type uint
18+
19+ func (typ Argon2Type ) String () string {
20+ switch typ {
21+ case Argon2d :
22+ return "argon2d"
23+ case Argon2i :
24+ return "argon2i"
25+ case Argon2id :
26+ return "argon2id"
27+ case Argon2 :
28+ return "argon2"
29+ default :
30+ return "unknown multiple value " + strconv .Itoa (int (typ ))
31+ }
32+ }
33+
34+ const (
35+ Argon2d Argon2Type = iota
36+ Argon2i
37+ Argon2id
38+ Argon2
39+ )
40+
41+ // Argon2 options
42+ type Opts struct {
1843 SaltLen int
1944 Time uint32
2045 Memory uint32
@@ -23,11 +48,11 @@ type Opt struct {
2348}
2449
2550var (
26- // 默认类型
27- defaultType = "argon2id"
51+ // default Type
52+ defaultType = Argon2id
2853
29- // 默认配置
30- defaultOpt = Opt {
54+ // default Options
55+ defaultOpts = Opts {
3156 SaltLen : 32 ,
3257 Time : 1 ,
3358 Memory : 64 * 1024 ,
@@ -36,18 +61,18 @@ var (
3661 }
3762)
3863
39- // 生成密钥
64+ // Generate Salted Hash
4065func GenerateSaltedHash (random io.Reader , password string ) (string , error ) {
41- return GenerateSaltedHashWithTypeAndOpt (random , password , defaultType , defaultOpt )
66+ return GenerateSaltedHashWithTypeAndOpts (random , password , defaultType , defaultOpts )
4267}
4368
44- // 生成密钥带类型
45- func GenerateSaltedHashWithType (random io.Reader , password string , typ string ) (string , error ) {
46- return GenerateSaltedHashWithTypeAndOpt (random , password , typ , defaultOpt )
69+ // Generate Salted Hash with type
70+ func GenerateSaltedHashWithType (random io.Reader , password string , typ Argon2Type ) (string , error ) {
71+ return GenerateSaltedHashWithTypeAndOpts (random , password , typ , defaultOpts )
4772}
4873
49- // 生成密钥带类型和设置
50- func GenerateSaltedHashWithTypeAndOpt (random io.Reader , password string , typ string , opt Opt ) (string , error ) {
74+ // Generate Salted Hash with type and opts
75+ func GenerateSaltedHashWithTypeAndOpts (random io.Reader , password string , typ Argon2Type , opt Opts ) (string , error ) {
5176 if len (password ) == 0 {
5277 return "" , errors .New ("go-cryptobin/argon2: Password length cannot be 0" )
5378 }
@@ -62,18 +87,24 @@ func GenerateSaltedHashWithTypeAndOpt(random io.Reader, password string, typ str
6287
6388 var unencodedPassword []byte
6489 switch typ {
65- case "argon2id" :
90+ case Argon2id :
6691 unencodedPassword = argon2 .IDKey (
6792 []byte (password ), []byte (salt ),
6893 argon2Time , argon2Memory ,
6994 argon2Threads , argon2KeyLen ,
7095 )
71- case "argon2i" , "argon2" :
96+ case Argon2i , Argon2 :
7297 unencodedPassword = argon2 .Key (
7398 []byte (password ), []byte (salt ),
7499 argon2Time , argon2Memory ,
75100 argon2Threads , argon2KeyLen ,
76101 )
102+ case Argon2d :
103+ unencodedPassword = argon2 .DKey (
104+ []byte (password ), []byte (salt ),
105+ argon2Time , argon2Memory ,
106+ argon2Threads , argon2KeyLen ,
107+ )
77108 default :
78109 return "" , errors .New ("go-cryptobin/argon2: Invalid Hash Type" )
79110 }
@@ -82,7 +113,7 @@ func GenerateSaltedHashWithTypeAndOpt(random io.Reader, password string, typ str
82113
83114 hash := fmt .Sprintf (
84115 "%s$%d$%d$%d$%d$%s$%s" ,
85- typ , argon2Time ,
116+ typ . String () , argon2Time ,
86117 argon2Memory , argon2Threads ,
87118 argon2KeyLen , salt ,
88119 encodedPassword ,
@@ -91,7 +122,7 @@ func GenerateSaltedHashWithTypeAndOpt(random io.Reader, password string, typ str
91122 return hash , nil
92123}
93124
94- // 验证密钥
125+ // Compare Hash With Password
95126func CompareHashWithPassword (hash , password string ) (bool , error ) {
96127 if len (hash ) == 0 || len (password ) == 0 {
97128 return false , errors .New ("go-cryptobin/argon2: Arguments cannot be zero length" )
@@ -124,6 +155,12 @@ func CompareHashWithPassword(hash, password string) (bool, error) {
124155 uint32 (time ), uint32 (memory ),
125156 uint8 (threads ), uint32 (keyLen ),
126157 )
158+ case "argon2d" :
159+ calculatedKey = argon2 .DKey (
160+ []byte (password ), salt ,
161+ uint32 (time ), uint32 (memory ),
162+ uint8 (threads ), uint32 (keyLen ),
163+ )
127164 default :
128165 return false , errors .New ("go-cryptobin/argon2: Invalid Password Hash" )
129166 }
@@ -135,6 +172,7 @@ func CompareHashWithPassword(hash, password string) (bool, error) {
135172 return true , nil
136173}
137174
175+ // generate salt with length
138176func generateSalt (random io.Reader , length int ) (string , error ) {
139177 unencodedSalt := make ([]byte , length )
140178
0 commit comments