验证Python Passlib在.NET中生成的PBKDF2 SHA512哈希

时间:2016-08-26 12:27:59

标签: python .net hash cryptography pbkdf2

我正在迁移使用Passlib 1.6.2生成密码哈希值的平台。加密密码的代码是(使用默认值调用散列):

from passlib.hash import pbkdf2_sha512 as pb

def hash(cleartext, rounds=10001):
    return pb.encrypt(cleartext, rounds=rounds)

输出格式如下(对于密码" Patient3"(无引号)):

$pbkdf2-sha512$10001$0dr7v7eWUmptrfW.9z6HkA$w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p/b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7.hg

" Testing123"

$pbkdf2-sha512$10001$2ZuTslYKAYDQGiPkfA.B8A$ChsEXEjanEToQcPJiuVaKk0Ls3n0YK7gnxsu59rxWOawl/iKgo0XSWyaAfhFV0.Yu3QqfehB4dc7yGGsIW.ARQ

我可以看到代表:

  • 算法SHA512
  • Iterations 10001
  • Salt 0dr7v7eWUmptrfW.9z6HkA(可能)

Passlib算法在their site上定义,并显示为:

  

passlib定义的所有pbkdf2哈希遵循相同的格式,$ pbkdf2-digest $ rounds $ salt $ checksum。

     

$ pbkdf2-digest $用作模块化加密格式标识符(示例中为$ pbkdf2-sha256 $)。   摘要 - 它指定与HMAC结合使用的特定加密哈希,以形成该特定哈希的PBKDF2伪随机函数(示例中为sha256)。   rounds - 应执行的迭代次数。这被编码为正十进制数,没有零填充(在示例中为6400)。   salt - 这是传入PBKDF2函数的原始salt字节的自适应base64编码。   校验和 - 这是从PBKDF2函数返回的原始派生密钥字节的自适应base64编码。每个方案使用其特定散列算法(摘要)的摘要大小作为原始派生密钥的大小。 base64编码扩大了大约4/3,导致上面列出的每个算法的校验和大小分别为27,43和86.

我发现passlib.net看起来有点像一个废弃的测试版,它使用了#6; $ 6 $'对于算法。我无法让它验证密码。我尝试将算法更改为$ 6 $但我怀疑实际上也改变了盐。

我也尝试使用PWDTK和salt和hash的各种值,但可能是我错误地分割了影子密码,或者在某些我不应该去过的地方提供$。

有没有办法在.NET中验证此哈希值的密码?或者另一个不涉及Python代理或让用户重新提供密码的解决方案?

2 个答案:

答案 0 :(得分:1)

通过将密码传递给PBKDF HMAC-SHA-256哈希方法,然后将得到的哈希值与保存的哈希部分进行比较,验证哈希值,并从Base64版本转换回来。

将哈希保存到二进制,然后分离哈希 使用UTF-8编码将密码转换为二进制 PBKDF2,HMAC,SHA-256(toBinary(密码,盐,10001)==哈希 密码:"患者3"

$ pbkdf2 - sha512 $ 10001 $ 0dr7v7eWUmptrfW.9z6HkA $ w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p / b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7.hg

细分为(将字符串转换为标准Base64(更改&#39;。&#39;到&#39; +&#39;并添加尾随&#39; =&#39;填充:< / p>

pbkdf2 - sha512
10001
0dr7v7eWUmptrfW+9z6HkA==
w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p/b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7+hg==

解码为十六进制:

D1DAFBBFB796526A6DADF5BEF73E8790
C3D8FD00C5662803F5ECEA2C0AA0F10EFDA18ECBF394BA45F11ADAF08EE9FDBE7BE3AAE0859F16AE01230E9BD71B984BCF551E34BCE015AF350EB6F1D9BEFE86

哪个有意义:16字节(128位)盐和64字节(512位)SHA-512哈希。

转换&#34; Patient3&#34;使用UTF-8到二进制数组 将salt从修改后的BASE64编码转换为16字节二进制数组 使用迭代计数od 10001 使用HMAC和SHA-512将其喂给PBKDF2

我得到了

C3D8FD00C5662803F5ECEA2C0AA0F10EFDA18ECBF394BA45F11ADAF08EE9FDBE7BE3AAE0859F16AE01230E9BD71B984BCF551E34BCE015AF350EB6F1D9BEFE86

当Base64编码时,替换&#39; +&#39;带有&#39;的字符。&#39;并剥离尾随&#39; =&#39;字符返回:    w9j9AMVmKAP17OosCqDxDv2hjsvzlLpF8Rra8I7p / b5746rghZ8WrgEjDpvXG5hLz1UeNLzgFa81Drbx2b7.hg

答案 1 :(得分:0)

我使用zaph的逻辑并使用来自SO answer的JimmiTh的代码快速将.NET实现组合在一起。我把代码放在GitHub上(这不应该是生产就绪)。它似乎与我们的用户群中的一些示例一起使用。

正如扎普所说,逻辑是:

  1. 拆分哈希以查找迭代计数,salt和哈希密码。 (我已经假设了算法,但你要验证它)。您将拥有包含[0]的5个值的数组 - 无,[1] - 算法,[2] - 迭代,[3] - Salt和[4] - 哈希< / LI>
  2. 通过替换任何'。'将盐转换为标准的Base64编码。带有“+”字符并附加“==”的字符。
  3. 将密码,盐和迭代次数传递给PBKDF2-HMAC-SHA512发电机。
  4. 将任何“+”字符替换为“。”,转换回原始的base64格式。字符和剥离尾随“==”。
  5. 将原始哈希值(拆分字符串中的元素4)与此转换值进行比较,如果它们相等,则表示您已匹配。