Python的Passlib哈希输出

1 投票
1 回答
2729 浏览
提问于 2025-04-18 16:35

我对使用 passlib 有点困惑。我有一段代码,用来用 N 种算法对 X 个密码进行哈希处理。

#!/usr/bin/python                                                               
from passlib.hash import *
from passlib.context import CryptContext
from passlib.utils import Base64Engine, h64
from base64 import b64decode
from binascii import hexlify

def hash_password(passwd):
    schemes = ["pbkdf2_sha1",
               "md5_crypt",
               "sha1_crypt",
               "sha256_crypt",
               "nthash",
               "lmhash"]

    print "Hashing \"%s\"" % passwd
    print "-----------------------------------------------"

    # Create the hashing context                                                
    pwd_context = CryptContext(schemes)

    for i in range(len(schemes)):
        pw_hash = pwd_context.encrypt(passwd, schemes[i])
        print "%s - %s" % (schemes[i], pw_hash)

    print "-----------------------------------------------"

def main():

    passwords = [line.rstrip('\n') for line in open("passwords.txt")]

    for i in range(len(passwords)):
        hash_password(passwords[i])

if __name__ == "__main__":
    main()

我得到了以下输出:

Hashing "Hello"
-----------------------------------------------
pbkdf2_sha1 - $pbkdf2$60000$ojQGACCEcM7ZW0vpnVMqRQ$M53EY/FaE4bn.5Peaagi51cza54
    pbkdf2_sha256 - $pbkdf2-      sha256$20000$4JxzLsWYk1KKUSoFwPifsw$6LCJ.389zCs4gaQuYTMTKUis7t/4yv.c9/mH/XFKEAo
md5_crypt - $1$uDGM/Vuu$jiygPs0AgWJQjdVkc5BbE0
sha1_crypt - $sha1$64000$ge8006iW$Ccn.2CfTJFHUNHKINw5uOaMP1U3v
sha256_crypt - $5$rounds=110000$BaeA4z3k.JSjarb5$veeo24NDYkEzMqhQqqUkjEst0FTqh9fWxxGPp/pO4xA
nthash - 916a8e7b1540ec179f196f8ddb603d85
lmhash - fda95fbeca288d44aad3b435b51404ee
-----------------------------------------------
Hashing "Password"
-----------------------------------------------
pbkdf2_sha1 - $pbkdf2$60000$fO.91/o/x/g/p3Qu5XxvLQ$HPcZm9FqiN59c7VurmE3gKPUlFk
pbkdf2_sha256 - $pbkdf2-sha256$20000$mrNWKkVISSll7D3nPGds7Q$AoEg6PiE7.YFQDxtmvKVlRk/i6niC1RVflFFZiZ1g.Y
md5_crypt - $1$0qgwC1qt$bpoGT56iTN2cHHXN3v0Hk/
sha1_crypt - $sha1$64000$D3aHiFZ3$8StKt6Kt0MVl.flOvuoulBJNPVG/
sha256_crypt - $5$rounds=110000$Zxm1u65zMawD1.2F$pqywgWCi556iuBTxemWIccy68IBQxqAKZgHYc0MAFY4
nthash - a4f49c406510bdcab6824ee7c30fd852
lmhash - e52cac67419a9a224a3b108f3fa6cb6d
-----------------------------------------------
Hashing "NewPassword"
-----------------------------------------------
pbkdf2_sha1 - $pbkdf2$60000$Uao1RgjhPEcI4dzbG8OYkw$TWkaN5uJ5HMh3tV75wEnMkYjZVI
pbkdf2_sha256 - $pbkdf2-sha256$20000$55zT2tub8/6f0zqHUOrdOw$voDY5VObZQieFDCqG2of1NO0NVMc4AVsznwqv9GzAhA
md5_crypt - $1$CkQuGd5z$1CcBnpwL4cFPOYiw958pZ1
sha1_crypt - $sha1$64000$hIbbDQIi$J.1kLykb3tzFUPrHZZ23TcSj.zAR
sha256_crypt - $5$rounds=110000$g7J4/8teBFGyKmI2$OakX25d3mePIAj9V1UYDWWBayaMfngWZ6fZOdgqg9l0
nthash - 91f172926b123808d76f4d40b1db18e5
lmhash - 09eeab5aa415d6e4d408e6b105741864

我有两个问题:

  1. 每次运行这个脚本时,得到的哈希结果都不一样,尽管我没有使用盐值,而且使用的是同一种算法。
  2. 我到处查找,但还是找不到如何从 .encrypt() 的结果中提取出合法的哈希值。这真的可能吗?我需要对编码做什么样的转换,因为 nt/lmhash 看起来没问题?

提前谢谢你。

1 个回答

2

passlib在你调用encrypt方法时,会自动为大多数哈希类型加盐,也就是说,它会在密码上加上一些额外的随机字符来增强安全性。

classmethod PasswordHash.encrypt(secret, **kwds)

使用特定格式的算法对密码进行处理,返回一个哈希字符串。

对于Passlib支持的大多数哈希,返回的字符串会包含:一个算法标识符、一个成本参数、盐字符串,最后是密码的哈希值。

这就解释了你在大多数哈希中看到的输出。nthashlmhash这两种哈希不支持加盐,所以它们的输出比较简单。

至于你的第二个问题,我想说一般来说你不应该单独提取实际的哈希值,因为passlib是设计用来使用encrypt返回的整个哈希字符串来验证给定的密码。不过如果你真的想要这样做,可以用$来分割返回的pw_hash,然后取最后一部分:

digest = pw_hash.split('$')[-1]

这对于像nthashlmhash这样的没有加盐的哈希也是有效的。

撰写回答