1
2
3
4
5
6
7 package pbkdf2
8
9 import (
10 "bytes"
11 "crypto/sha1"
12 "crypto/sha256"
13 "crypto/sha512"
14 "encoding/hex"
15 "hash"
16 "strings"
17 "testing"
18 )
19
20 type testVector struct {
21 n string
22 p string
23 s string
24 c int
25 l int
26 o string
27 }
28
29 type testKeyGen struct {
30 h func() hash.Hash
31 vectors []testVector
32 }
33
34 var cases = []testKeyGen{
35 {
36 h: sha1.New,
37 vectors: []testVector{
38
39 {
40 n: "SHA-1 1 iter",
41 p: "password",
42 s: "salt",
43 c: 1,
44 l: 20,
45 o: "0c 60 c8 0f 96 1f 0e 71 f3 a9 b5 24 af 60 12 06 2f e0 37 a6",
46 },
47 {
48 n: "SHA-1 2 iters",
49 p: "password",
50 s: "salt",
51 c: 2,
52 l: 20,
53 o: "ea 6c 01 4d c7 2d 6f 8c cd 1e d9 2a ce 1d 41 f0 d8 de 89 57",
54 },
55 {
56 n: "SHA-1 4096 iters",
57 p: "password",
58 s: "salt",
59 c: 4096,
60 l: 20,
61 o: "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1",
62 },
63 {
64 n: "SHA-1 4096 iters, longer pw/salt/dk_length",
65 p: "passwordPASSWORDpassword",
66 s: "saltSALTsaltSALTsaltSALTsaltSALTsalt",
67 c: 4096,
68 l: 25,
69 o: "3d 2e ec 4f e4 1c 84 9b 80 c8 d8 36 62 c0 e4 4a 8b 29 1a 96 4c f2 f0 70 38",
70 },
71 {
72 n: "SHA-1 4096 iters, embedded nulls, short dk",
73 p: "pass\x00word",
74 s: "sa\x00lt",
75 c: 4096,
76 l: 16,
77 o: "56 fa 6a a7 55 48 09 9d cc 37 d7 f0 34 25 e0 c3",
78 },
79
80 {
81 n: "SHA-1 3 iters",
82 p: "password",
83 s: "salt",
84 c: 3,
85 l: 20,
86 o: "6b 4e 26 12 5c 25 cf 21 ae 35 ea d9 55 f4 79 ea 2e 71 f6 ff",
87 },
88 },
89 },
90 {
91 h: sha256.New224,
92 vectors: []testVector{
93
94 {
95 n: "SHA-224 1 iter",
96 p: "password",
97 s: "salt",
98 c: 1,
99 l: 28,
100 o: "3c 19 8c bd b9 46 4b 78 57 96 6b d0 5b 7b c9 2b c1 cc 4e 6e 63 15 5d 4e 49 05 57 fd",
101 },
102 {
103 n: "SHA-224 1000 iter",
104 p: "password",
105 s: "salt",
106 c: 1000,
107 l: 28,
108 o: "d3 bc f3 20 fd 91 89 08 ea fc aa 46 0f af 40 e2 01 f6 50 8d 4e 6f 3d 9c 1c 0a bd 30",
109 },
110 },
111 },
112 {
113 h: sha256.New,
114 vectors: []testVector{
115
116 {
117 n: "SHA-256 1 iter",
118 p: "password",
119 s: "salt",
120 c: 1,
121 l: 32,
122 o: "12 0f b6 cf fc f8 b3 2c 43 e7 22 52 56 c4 f8 37 a8 65 48 c9 2c cc 35 48 08 05 98 7c b7 0b e1 7b",
123 },
124 {
125 n: "SHA-256 2 iters",
126 p: "password",
127 s: "salt",
128 c: 2,
129 l: 32,
130 o: "ae 4d 0c 95 af 6b 46 d3 2d 0a df f9 28 f0 6d d0 2a 30 3f 8e f3 c2 51 df d6 e2 d8 5a 95 47 4c 43",
131 },
132 {
133 n: "SHA-256 4096 iter",
134 p: "password",
135 s: "salt",
136 c: 4096,
137 l: 32,
138 o: "c5 e4 78 d5 92 88 c8 41 aa 53 0d b6 84 5c 4c 8d 96 28 93 a0 01 ce 4e 11 a4 96 38 73 aa 98 13 4a",
139 },
140
141
142
143
144
145
146
147
148 {
149 n: "SHA-256 4096 iters, longer pw/salt/dk_length",
150 p: "passwordPASSWORDpassword",
151 s: "saltSALTsaltSALTsaltSALTsaltSALTsalt",
152 c: 4096,
153 l: 40,
154 o: "34 8c 89 db cb d3 2b 2f 32 d8 14 b8 11 6e 84 cf 2b 17 34 7e bc 18 00 18 1c 4e 2a 1f b8 dd 53 e1 c6 35 51 8c 7d ac 47 e9",
155 },
156 {
157 n: "SHA-256 4096 iters, embedded nulls, short dk",
158 p: "pass\x00word",
159 s: "sa\x00lt",
160 c: 4096,
161 l: 16,
162 o: "89 b6 9d 05 16 f8 29 89 3c 69 62 26 65 0a 86 87",
163 },
164
165 {
166 n: "SHA-256 1 iter, 2",
167 p: "password",
168 s: "salt",
169 c: 1,
170 l: 32,
171 o: "12 0f b6 cf fc f8 b3 2c 43 e7 22 52 56 c4 f8 37 a8 65 48 c9 2c cc 35 48 08 05 98 7c b7 0b e1 7b ",
172 },
173 {
174 n: "SHA-256 1000 iter",
175 p: "password",
176 s: "salt",
177 c: 1000,
178 l: 32,
179 o: "63 2c 28 12 e4 6d 46 04 10 2b a7 61 8e 9d 6d 7d 2f 81 28 f6 26 6b 4a 03 26 4d 2a 04 60 b7 dc b3 ",
180 },
181 },
182 },
183 {
184 h: sha512.New384,
185 vectors: []testVector{
186
187 {
188 n: "SHA-384 1 iter",
189 p: "password",
190 s: "salt",
191 c: 1,
192 l: 48,
193 o: "c0 e1 4f 06 e4 9e 32 d7 3f 9f 52 dd f1 d0 c5 c7 19 16 09 23 36 31 da dd 76 a5 67 db 42 b7 86 76 b3 8f c8 00 cc 53 dd b6 42 f5 c7 44 42 e6 2b e4 ",
194 },
195 {
196 n: "SHA-384 1000 iter",
197 p: "password",
198 s: "salt",
199 c: 1000,
200 l: 48,
201 o: "3b d3 7e 22 36 94 1d 4a 77 b1 b5 b7 14 c6 f9 13 fa bb 6b 08 41 a6 d7 d8 65 6b 99 d6 11 e9 00 fe 06 ed b9 3b 5b 80 9e fa a9 67 8b 63 5c e5 13 e0 ",
202 },
203 },
204 },
205 {
206 h: sha512.New,
207 vectors: []testVector{
208
209 {
210 n: "SHA-512 1 iter",
211 p: "password",
212 s: "salt",
213 c: 1,
214 l: 64,
215 o: "86 7f 70 cf 1a de 02 cf f3 75 25 99 a3 a5 3d c4 af 34 c7 a6 69 81 5a e5 d5 13 55 4e 1c 8c f2 52 c0 2d 47 0a 28 5a 05 01 ba d9 99 bf e9 43 c0 8f 05 02 35 d7 d6 8b 1d a5 5e 63 f7 3b 60 a5 7f ce ",
216 },
217 {
218 n: "SHA-512 1000 iter",
219 p: "password",
220 s: "salt",
221 c: 1000,
222 l: 64,
223 o: "af e6 c5 53 07 85 b6 cc 6b 1c 64 53 38 47 31 bd 5e e4 32 ee 54 9f d4 2f b6 69 57 79 ad 8a 1c 5b f5 9d e6 9c 48 f7 74 ef c4 00 7d 52 98 f9 03 3c 02 41 d5 ab 69 30 5e 7b 64 ec ee b8 d8 34 cf ec ",
224 },
225 },
226 },
227 }
228
229 func TestKey(t *testing.T) {
230 for _, c := range cases {
231 c := c
232 for _, v := range c.vectors {
233 v := v
234 t.Run(v.n, func(t *testing.T) {
235 t.Parallel()
236 expected, err := hex.DecodeString(strings.Replace(v.o, " ", "", -1))
237 if err != nil {
238 t.Fatalf("error decoding expected output: %v", err)
239 }
240 key := Key([]byte(v.p), []byte(v.s), v.c, v.l, c.h)
241 if !bytes.Equal(expected, key) {
242 t.Errorf("incorrect derived key\n Got: %s\n Want: %s\n", keyTuples(key), v.o)
243 }
244 })
245 }
246 }
247 }
248
249 func keyTuples(key []byte) string {
250 var xs []string
251 for len(key) > 0 {
252 xs = append(xs, hex.EncodeToString(key[0:1]))
253 key = key[1:]
254 }
255 return strings.Join(xs, " ")
256 }
257
View as plain text