【问题标题】:Pbkdf2_sha256 encryptionpbkdf2_sha256 加密
【发布时间】:2021-01-14 03:23:14
【问题描述】:

大家好,我正在研究 Pbkdf2_sha256 的工作原理。

这是我目前正在研究的一些破解哈希

PBKDF2 pbkdf2_sha256$10000$005OtPxTXhPq$K/2GplWPJsBVj+qbgdKW8YEteQyUkIiquT5MaOhPo4Y=:harry
PBKDF2 pbkdf2_sha256$10000$00Qhibr5Mbeg$l9grYueDrl3qN3NA7e9j5PodgV1XkGTz0Z6ajhF99AY=:radio
PBKDF2 pbkdf2_sha256$10000$00h7h0g1ZKE1$YEobSm/y+cFg/VXhU4gGYJ6eOkZ68jhJ5axDu68Dack=:momo
PBKDF2 pbkdf2_sha256$10000$01JMkfGk1RXh$vD+GGZshw5kExtZOpl5+Lht3xECULdbNVOesoTicxto=:fred
PBKDF2 pbkdf2_sha256$10000$01vkw1viCg4J$2hjlbq10Jh/Su3yqjKfYCnCSt1WlKcKJtsqDET618M0=:get
PBKDF2 pbkdf2_sha256$10000$01wayF5JLVSZ$2/9COWqb6SZG/raqabtU8fNBzkrt2puN7SaKw0U7jBs=:987456321

这是我计算哈希的代码和输出

>>> from passlib.hash import pbkdf2_sha256
>>> from passlib.utils.binary import ab64_decode
>>> print(pbkdf2_sha256.hash("harry", rounds=10000, salt=ab64_decode(b'005OtPxTXhPq')))
$pbkdf2-sha256$10000$005OtPxTXhPq$l9LhRMPBW.EEdlBE9b.P0Z70Kxidl9EJhfGK7FiLUHA

比较这两者,你可以看出区别。

$pbkdf2_sha256$10000$005OtPxTXhPq$K/2GplWPJsBVj+qbgdKW8YEteQyUkIiquT5MaOhPo4Y=
$pbkdf2-sha256$10000$005OtPxTXhPq$l9LhRMPBW.EEdlBE9b.P0Z70Kxidl9EJhfGK7FiLUHA

谁能解释一下是什么原因造成的,我该如何计算正确的哈希值?

提前致谢!

【问题讨论】:

  • 你怎么知道“破解”的哈希值是正确的?这些破解哈希中的盐值非常短。
  • “破解”散列使用 Unix 密码散列中未使用的 base64 编码。 '+' 字符通常不会出现在这样的散列中。此外,在 Unix 密码哈希中省略了 '=' 填充字符。这证明破解的哈希列表中有问题。无论是哪种格式,它都与 passlib 不兼容
  • @PresidentJamesK.Polk 这些哈希来自一个哈希破解社区,我很确定破解的那些已经过验证。原始列表有大约 75k 行,所有盐的长度都相同。附加的 = 看起来确实很可疑,因为它出现在 :[plain] 之前的所有行中

标签: python hash pbkdf2


【解决方案1】:

正如评论中已经提到的,发布的数据具有不同于 passlib 的格式:passlib 格式解释为here。盐和哈希(校验和)是 Base64 编码的。使用了一个特殊的 Base64 变体,解释为 here:填充 (=) 和空格被省略,. 被应用 +

另一方面,发布数据的哈希是标准 Base64 编码的(即使用+ 而不是.)和填​​充(=)。 此外,盐是 UTF8 解码的。

如果考虑到这一点,盐和哈希是相同的。下面的代码从posted数据中判断出passlib数据,并比较salt和hash,其中posted数据的salt和hash以passlib格式显示(即用passlib Base64 变体和 Base64 编码盐):

from passlib.hash import pbkdf2_sha256
from base64 import b64decode
from passlib.utils.binary import ab64_encode

def hashAndCompare(crackedHash):
    
    crackedChain = crackedHash.split('$')   
    #crackedChainDigest = crackedChain[0]
    crackedChainRounds = crackedChain[1]
    crackedChainSalt = crackedChain[2]
    crackedChainSaltPasslibFormat = ab64_encode(crackedChainSalt.encode('utf8')).decode('utf8')
    crackedChainHashData = crackedChain[3].split(':')
    crackedChainHash = crackedChainHashData[0]
    crackedChainHashPasslibFormat = ab64_encode(b64decode(crackedChainHash)).decode('utf8')
    crackedChainData = crackedChainHashData[1]
    
    passlibHash = pbkdf2_sha256.hash(crackedChainData, rounds=crackedChainRounds, salt=crackedChainSalt.encode('utf8')) 
    passlibChain = passlibHash.split('$')
    passlibChainSalt = passlibChain[3]
    passlibChainHash = passlibChain[4]
    
    print('Passlib: Hash: {0} Salt: {1}\nCracked: Hash: {2} Salt: {3}\n'.format(passlibChainHash, passlibChainSalt, crackedChainHashPasslibFormat, crackedChainSaltPasslibFormat))

hashAndCompare('pbkdf2_sha256$10000$005OtPxTXhPq$K/2GplWPJsBVj+qbgdKW8YEteQyUkIiquT5MaOhPo4Y=:harry')
hashAndCompare('pbkdf2_sha256$10000$00Qhibr5Mbeg$l9grYueDrl3qN3NA7e9j5PodgV1XkGTz0Z6ajhF99AY=:radio')
hashAndCompare('pbkdf2_sha256$10000$00h7h0g1ZKE1$YEobSm/y+cFg/VXhU4gGYJ6eOkZ68jhJ5axDu68Dack=:momo')
hashAndCompare('pbkdf2_sha256$10000$01JMkfGk1RXh$vD+GGZshw5kExtZOpl5+Lht3xECULdbNVOesoTicxto=:fred')
hashAndCompare('pbkdf2_sha256$10000$01vkw1viCg4J$2hjlbq10Jh/Su3yqjKfYCnCSt1WlKcKJtsqDET618M0=:get')
hashAndCompare('pbkdf2_sha256$10000$01wayF5JLVSZ$2/9COWqb6SZG/raqabtU8fNBzkrt2puN7SaKw0U7jBs=:987456321')

盐和哈希与一致编码相同:

Passlib: Hash: K/2GplWPJsBVj.qbgdKW8YEteQyUkIiquT5MaOhPo4Y Salt: MDA1T3RQeFRYaFBx
Cracked: Hash: K/2GplWPJsBVj.qbgdKW8YEteQyUkIiquT5MaOhPo4Y Salt: MDA1T3RQeFRYaFBx

Passlib: Hash: l9grYueDrl3qN3NA7e9j5PodgV1XkGTz0Z6ajhF99AY Salt: MDBRaGlicjVNYmVn
Cracked: Hash: l9grYueDrl3qN3NA7e9j5PodgV1XkGTz0Z6ajhF99AY Salt: MDBRaGlicjVNYmVn

Passlib: Hash: YEobSm/y.cFg/VXhU4gGYJ6eOkZ68jhJ5axDu68Dack Salt: MDBoN2gwZzFaS0Ux
Cracked: Hash: YEobSm/y.cFg/VXhU4gGYJ6eOkZ68jhJ5axDu68Dack Salt: MDBoN2gwZzFaS0Ux

Passlib: Hash: vD.GGZshw5kExtZOpl5.Lht3xECULdbNVOesoTicxto Salt: MDFKTWtmR2sxUlho
Cracked: Hash: vD.GGZshw5kExtZOpl5.Lht3xECULdbNVOesoTicxto Salt: MDFKTWtmR2sxUlho

Passlib: Hash: 2hjlbq10Jh/Su3yqjKfYCnCSt1WlKcKJtsqDET618M0 Salt: MDF2a3cxdmlDZzRK
Cracked: Hash: 2hjlbq10Jh/Su3yqjKfYCnCSt1WlKcKJtsqDET618M0 Salt: MDF2a3cxdmlDZzRK

Passlib: Hash: 2/9COWqb6SZG/raqabtU8fNBzkrt2puN7SaKw0U7jBs Salt: MDF3YXlGNUpMVlNa
Cracked: Hash: 2/9COWqb6SZG/raqabtU8fNBzkrt2puN7SaKw0U7jBs Salt: MDF3YXlGNUpMVlNa

【讨论】:

    【解决方案2】:

    Django 使用该格式,并且 passlib 具有该格式的功能:Django 1.4 Hashes

    所以,我在 python 的 shell 中做了这个:

    >>> from passlib.hash import django_pbkdf2_sha256
    >>> secret = 'harry'
    >>> hash = 'pbkdf2_sha256$10000$005OtPxTXhPq$K/2GplWPJsBVj+qbgdKW8YEteQyUkIiquT5MaOhPo4Y='
    >>> django_pbkdf2_sha256.verify(secret, hash)
    True
    >>> rounds = hash.split('$')[1]
    >>> salt = hash.split('$')[2]
    >>> django_pbkdf2_sha256.hash(secret, rounds=rounds, salt=salt) == hash
    True
    

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 2021-03-14
      • 2013-06-30
      • 1970-01-01
      • 2013-07-06
      • 2020-12-01
      • 2022-11-19
      • 2019-01-07
      • 2018-02-14
      相关资源
      最近更新 更多