我正在学习Python.我无法弄清楚为什么hashlib.sha512(salt + password).hexdigest()
不给出预期的结果.
我正在寻找相当于Ulrich Drepper的sha512crypt.c算法的纯Python实现.(我花了一些时间来弄清楚我在寻找什么.)
根据crypt
我的Ubuntu 12.04系统的手册页,crypt使用SHA-512(因为字符串以$ 6 $开头).
当我调用Python的系统crypt包装器(即crypt.crypt())时,下面的代码验证行为是否符合预期.我想使用hashlib.sha512或其他一些Python lib来产生与crypt.crypt()相同的结果.怎么样?
此代码显示了我遇到的问题:
import hashlib, crypt ctype = "6" #for sha512 (see man crypt) salt = "qwerty" insalt = '${}${}$'.format(ctype, salt) password = "AMOROSO8282" value1 = hashlib.sha512(salt + password).hexdigest() #what's wrong with this one? value2 = crypt.crypt(password, insalt) #this one is correct on Ubuntu 12.04 if not value1 == value2: print("{}\n{}\n\n".format(value1, value2))
根据crypt手册页,SHA-512是86个字符.crypt()
上面代码中的调用符合这一点.但是,hashlib.sha512的输出超过了86个字符,所以在这两个实现之间有所作为......
以下是那些不想运行代码的人的输出:
051f606027bd42c1aae0d71d049fdaedbcfd28bad056597b3f908d22f91cbe7b29fd0cdda4b26956397b044ed75d50c11d0c3331d3cb157eecd9481c4480e455 $6$qwerty$wZZxE91RvJb4ETR0svmCb69rVCevicDV1Fw.Y9Qyg9idcZUioEoYmOzAv23wyEiNoyMLuBLGXPSQbd5ETanmq/
另一种尝试基于此处的初步反馈.还没有成功:
import hashlib, crypt, base64 ctype = "6" #for sha512 (see man crypt) salt = "qwerty" insalt = '${}${}$'.format(ctype, salt) password = "AMOROSO8282" value1 = base64.b64encode(hashlib.sha512(salt + password).digest()) value2 = crypt.crypt(password, insalt) #this one is correct if not value1 == value2: print("{}\n{}\n\n".format(value1, value2))
MountainX.. 11
这是解决方案.在另一个问题上还有更多细节:sha512_crypt.c的Python实现,其中显示了passlib的后端包含sha512_crypt的纯Python实现(如果crypt.crypt()不可用,则调用Python实现OS).
$ sudo pip install passlib
import passlib.hash, crypt ctype = "6" #for sha512 (see man crypt) salt = "qwerty" insalt = '${}${}$'.format(ctype, salt) password = "AMOROSO8282" value1 = sha512_crypt.encrypt(password, salt=salt, rounds=5000) value2 = crypt.crypt(password, insalt) if not value1 == value2: print("algorithms do not match") print("{}\n{}\n\n".format(value1, value2))
这是输出:
$6$qwerty$wZZxE91RvJb4ETR0svmCb69rVCevicDV1Fw.Y9Qyg9idcZUioEoYmOzAv23wyEiNoyMLuBLGXPSQbd5ETanmq/ $6$qwerty$wZZxE91RvJb4ETR0svmCb69rVCevicDV1Fw.Y9Qyg9idcZUioEoYmOzAv23wyEiNoyMLuBLGXPSQbd5ETanmq/
一个关键点是Passlib有一个sha512_crypt的纯Python实现,它将在系统没有当前Linux系统具有的crypt实现时使用(例如,http://www.akkadia.org/drepper/SHA-crypt .txt).
请在此处查看PassLib的文档:
passlib - 用于python的密码哈希库 - Google Project Hosting
https://code.google.com/p/passlib/
Passlib 1.6.2文档 - Passlib v1.6.2文档
http://pythonhosted.org/passlib/
passlib-users - Google网上论坛
https://groups.google.com/forum/#!forum/passlib-users
新应用程序快速入门指南 - Passlib v1.6.2文档
http://pythonhosted.org/passlib/new_app_quickstart.html#sha512-crypt
passlib.hash.sha512_crypt - SHA-512 Crypt - Passlib v1.6.2文档
http://pythonhosted.org/passlib/lib/passlib.hash.sha512_crypt.html#passlib.hash.sha512_crypt
您的密码长度不同,这是因为crypt()
输出是base64编码的,您使用hexdigest value1
.
而不是hexdigest,你应该尝试做类似的事情
value1 = crypt_base64(hashlib.sha512(salt + password))
与crypt_base64
喜欢的bash执行,最后的部分
doHash()
功能.
手册crypt
是不精确的(甚至是误导性的).所使用的算法crypt
与"MD5","SHA-256"或"SHA-512"的绰号其实都是算法建基于这些基础.它们是基于密码的密钥派生函数,使用哈希来执行密钥强化.
一个好的密码哈希算法有两个属性:它必须将密码与一个独特的盐组合在一起(以防止一次破解许多密码的尝试),并且它必须很慢(因为攻击者需要比攻击者更多地伤害攻击者,因为攻击者需要尝试大量的组合).像MD5和SHA系列这样的日常哈希算法设计得尽可能快,同时仍具有所需的安全属性.构建密码哈希算法的一种方法是采用加密哈希算法并多次迭代.虽然这并不理想(因为有更好的技术使得构建专用硬件以进行密码破解变得更加困难),但它已经足够了.
在维基百科的文章crypt(3)
提供了一个简要的解释和有指向主要来源.Linux和FreeBSD的手册页很差,但是Solaris有足够的信息不会产生误导(按照链接crypt.conf(4)
然后crypt_sha512
和其他链接).您还可以在纯文本中阅读ubuntu 13.04中的用户密码吗?和是否有重复在Solaris 11哈希程序?我可以添加一些吗?
计算crypt
Python 输出的正确方法是调用crypt.crypt
.
这是解决方案.在另一个问题上还有更多细节:sha512_crypt.c的Python实现,其中显示了passlib的后端包含sha512_crypt的纯Python实现(如果crypt.crypt()不可用,则调用Python实现OS).
$ sudo pip install passlib
import passlib.hash, crypt ctype = "6" #for sha512 (see man crypt) salt = "qwerty" insalt = '${}${}$'.format(ctype, salt) password = "AMOROSO8282" value1 = sha512_crypt.encrypt(password, salt=salt, rounds=5000) value2 = crypt.crypt(password, insalt) if not value1 == value2: print("algorithms do not match") print("{}\n{}\n\n".format(value1, value2))
这是输出:
$6$qwerty$wZZxE91RvJb4ETR0svmCb69rVCevicDV1Fw.Y9Qyg9idcZUioEoYmOzAv23wyEiNoyMLuBLGXPSQbd5ETanmq/ $6$qwerty$wZZxE91RvJb4ETR0svmCb69rVCevicDV1Fw.Y9Qyg9idcZUioEoYmOzAv23wyEiNoyMLuBLGXPSQbd5ETanmq/
一个关键点是Passlib有一个sha512_crypt的纯Python实现,它将在系统没有当前Linux系统具有的crypt实现时使用(例如,http://www.akkadia.org/drepper/SHA-crypt .txt).
请在此处查看PassLib的文档:
passlib - 用于python的密码哈希库 - Google Project Hosting
https://code.google.com/p/passlib/
Passlib 1.6.2文档 - Passlib v1.6.2文档
http://pythonhosted.org/passlib/
passlib-users - Google网上论坛
https://groups.google.com/forum/#!forum/passlib-users
新应用程序快速入门指南 - Passlib v1.6.2文档
http://pythonhosted.org/passlib/new_app_quickstart.html#sha512-crypt
passlib.hash.sha512_crypt - SHA-512 Crypt - Passlib v1.6.2文档
http://pythonhosted.org/passlib/lib/passlib.hash.sha512_crypt.html#passlib.hash.sha512_crypt