PBKDF2-HMAC-SHA2 测试向量
Posted
技术标签:
【中文标题】PBKDF2-HMAC-SHA2 测试向量【英文标题】:PBKDF2-HMAC-SHA2 test vectors 【发布时间】:2011-07-05 01:40:24 【问题描述】:RFC6070 中有 PBKDF2-HMAC-SHA1 的测试向量。 RFC4231 中有 HMAC-SHA2 的测试向量。
但到目前为止,我还没有在任何地方找到 PBKDF2-HMAC-SHA2 的测试向量。
我对 SHA256 最感兴趣,所以我将发布一些我用我的实现计算的向量。如果有人可以验证/确认他们,或者贡献他们自己的,我会很高兴。
【问题讨论】:
您可以考虑编写一个 RFC 来描述如何在 RFC 2898 中使用 PBKDF2-HMAC-SHA256,并且还包括测试向量。你应该对所有的 SHA2 哈希值都这样做。 【参考方案1】:作为RFC-7914(scrypt 规范)的一部分,为 PBKDF2 和 HMAC-SHA-256 提供了测试向量(因为 scrypt内部使用PBKDF2)。
他们在这里:
PBKDF2-HMAC-SHA-256 (P="passwd", S="salt",
c=1, dkLen=64) =
55 ac 04 6e 56 e3 08 9f ec 16 91 c2 25 44 b6 05
f9 41 85 21 6d de 04 65 e6 8b 9d 57 c2 0d ac bc
49 ca 9c cc f1 79 b6 45 99 16 64 b3 9d 77 ef 31
7c 71 b8 45 b1 e3 0b d5 09 11 20 41 d3 a1 97 83
PBKDF2-HMAC-SHA-256 (P="Password", S="NaCl",
c=80000, dkLen=64) =
4d dc d8 f6 0b 98 be 21 83 0c ee 5e f2 27 01 f9
64 1a 44 18 d0 4c 04 14 ae ff 08 87 6b 34 ab 56
a1 d4 25 a1 22 58 33 54 9a db 84 1b 51 c9 b3 17
6a 27 2b de bb a1 d0 78 47 8f 62 b3 97 f3 3c 8d
有趣的是,dkLen
超过了32
(SHA-256 块的大小),因此它确实测试了中间散列块的串联是否有效。
【讨论】:
【参考方案2】:我可能最终应该基于这个问题发布我前一段时间所做的事情!
在my Github repository,我已经为
编译了测试向量 PBKDF2-HMAC-SHA-512 PBKDF2-HMAC-SHA-384 PBKDF2-HMAC-SHA-256 PBKDF2-HMAC-SHA-224 PBKDF2-HMAC-SHA-1 对于疯狂的人或那些拥有甚至没有 SHA-1 支持的古老系统的人: PBKDF2-HMAC-MD5测试从 RFC6070 和上面@ChristianAichinger 对 PBKDF2-HMAC-SHA-256 的回答开始,并添加了几十个以实施更严格的测试,例如围绕特定大小的密码和盐 (15 /16/17 字节、63/64/65 字节、127/128/129 字节、1025 字节等)、大迭代计数、大输出大小计数等等。
然后我收集了许多 PBKDF2 实例,并针对我能够找到的每个主要实现验证了这些测试向量(所有这些都包含在上述存储库中,有时包括 Windows MinGW 可执行文件,通常包括 Linux 编译指令),包括
Python (hashlib) Python(warner 的自定义代码) C (OpenSSL) C (PolarSSL) C++(加密货币) .NET 4.5(@Jither 的 DeriveBytes) SQL Server(自定义代码,目前仅限 PBKDF2-HMAC-SHA-1 和 PBKDF2-HMAC-SHA-512)鉴于我在使用 5 种不同语言并使用多个主要加密库的 7 种实现中看到相同的结果,我非常有信心提供的测试向量不仅准确,而且提供的实现可以作为一个集合使用验证所需的任何其他测试向量集。如果他们都同意,那就对了。
【讨论】:
我认为如果您以比 ODS 电子表格更易于访问的格式分发您的测试向量,人们会发现它们更有用——我认为 JSON 格式是理想的。【参考方案3】:我 implemented PBKDF2 使用 Python 中的标准 hashlib 和 hmac 模块,并根据 RFC 6070 向量和 vectors you posted 检查了输出 - 它匹配。
这是我使用较大的dkLen
得到的向量,以匹配较大的摘要输出大小。这是pbkdf2-test-vectors.py sha256
的输出,运行大约需要10分钟。
PBKDF2 HMAC-SHA256 Test Vectors
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 1
dkLen = 32
Output:
DK = 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 (32 octets)
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 2
dkLen = 32
Output:
DK = 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 (32 octets)
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 4096
dkLen = 32
Output:
DK = 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 (32 octets)
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 16777216
dkLen = 32
Output:
DK = cf 81 c6 6f e8 cf c0 4d
1f 31 ec b6 5d ab 40 89
f7 f1 79 e8 9b 3b 0b cb
17 ad 10 e3 ac 6e ba 46 (32 octets)
Input:
P = "passwordPASSWORDpassword" (24 octets)
S = "saltSALTsaltSALTsaltSALTsaltSALTsalt" (36 octets)
c = 4096
dkLen = 40
Output:
DK = 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 (40 octets)
Input:
P = "pass\0word" (9 octets)
S = "sa\0lt" (5 octets)
c = 4096
dkLen = 16
Output:
DK = 89 b6 9d 05 16 f8 29 89
3c 69 62 26 65 0a 86 87 (16 octets)
【讨论】:
我能够使用 SJCL library 在 javascript 中正确重现您的所有结果。 除了改变输出大小外,可能还需要扩展测试用例 5 中的输入大小以产生与 RFC 测试向量相同的效果 - 24 个八位字节的密码密码超过了输出大小SHA1 输出,但不超过 SHA256 输出的大小。这可能会遗漏一些 RFC 测试向量所遵循的代码路径——尽管可能不会;我怀疑密码必须超过 64 字节的块大小才能在任何一种情况下产生影响。 警告:PBKDF2 的“默认”字符编码为 UTF-8。您可能还想测试特殊字符。 Java 会失败,因为它只符合 Windows-1252(ASCII + 128 个特殊字符)。 @MaartenBodewes Java 对字符串和字符使用“Unicode”(实际上是 UTF-16),并支持数百种与字节之间的 I/O 编码和类似的东西,如加密。 default 编码不同;对于 Windows,它(通常?) cp1252 但其他平台不同。对于加密来说,完全可重现的数据至关重要,因此您应该使用显式编码而不是默认编码,通常使用 UTF-8 来支持最广泛的数据,尤其是在 2898 推荐(但不要求)UTF-8 的情况下。 有没有人考虑过将其放入 RFC 中?【参考方案4】:PBKDF2-HMAC-SHA256 的测试向量:
输入值取自 RFC6070; c 是轮数。
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 1
dkLen = 20
Output:
DK = 12 0f b6 cf fc f8 b3 2c 43 e7 22 52 56 c4 f8 37 a8 65 48 c9
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 2
dkLen = 20
Output:
DK = ae 4d 0c 95 af 6b 46 d3 2d 0a df f9 28 f0 6d d0 2a 30 3f 8e
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 4096
dkLen = 20
Output:
DK = c5 e4 78 d5 92 88 c8 41 aa 53 0d b6 84 5c 4c 8d 96 28 93 a0
Input:
P = "password" (8 octets)
S = "salt" (4 octets)
c = 16777216
dkLen = 20
Output:
DK = cf 81 c6 6f e8 cf c0 4d 1f 31 ec b6 5d ab 40 89 f7 f1 79 e8
Input:
P = "passwordPASSWORDpassword" (24 octets)
S = "saltSALTsaltSALTsaltSALTsaltSALTsalt" (36 octets)
c = 4096
dkLen = 25
Output:
DK = 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
Input:
P = "pass\0word" (9 octets)
S = "sa\0lt" (5 octets)
c = 4096
dkLen = 16
Output:
DK = 89 b6 9d 05 16 f8 29 89 3c 69 62 26 65 0a 86 87
【讨论】:
我认为dkLen = 20
反映了摘要大小,因此对于SHA-256您应该使用32。dkLen = 25
应该大于摘要大小,以便它覆盖处理多个@的代码路径987654325@块;也许 40。
@aaz:没有。dkLen
是Derived Key Length。摘要大小由hlen
在算法中指定,这不是直接输入到 PBKDF2 函数...
@ircmaxell – 是的。我的意思是选择测试用例的dkLen
以匹配正在使用的PRF 的hLen
。因此,当为不同的 PRF 调整测试用例时,应该调整 dkLen
。
dkLen = 32 会有很大帮助,因为如果它低于 32,它只会剪掉多余的八位字节
至少应该有一个 > 32 的测试。另一方面,我复制上述测试值没有问题。以上是关于PBKDF2-HMAC-SHA2 测试向量的主要内容,如果未能解决你的问题,请参考以下文章