在Python 3.1.1中生成密码
我想用用户输入的字符串来生成密码,我正在看的书推荐使用 sha
,因为它比 md5
更安全。
不过,sha
现在已经不推荐使用了,所以我现在用 hashlib
模块来加密我的字符串,做法和这里展示的类似:http://docs.python.org/py3k/library/hashlib.html#module-hashlib。
import os
import hashlib
from getpass import getpass
print('Username: ' + os.environ['USER'])
passwd = getpass('Password: ')
h = hashlib.md5()
h.update(passwd.encode())
passwd_encrypt = h.hexdigest()
接下来,我把 passwd_encrypt
和一个包含用户名和加密密码的普通 ASCII 文件进行比较,文件内容大致是这样的:
THO 5f4dcc3b5aa765d61d8327deb882cf99
这种加密密码的方法合适吗?还是说有更好的方法?我也想知道以这种方式存储密码是否合适,还有什么其他的选择。
谢谢
2 个回答
-1
把密码的哈希值和保存的哈希值进行比较,是一种合适的身份验证方法。
7
其实没有所谓的“sha”算法。sha1算法比md5要强很多,因为md5已经完全被破解了。我相信现在有一种算法,生成碰撞只需要微秒级的时间。
虽然sha1算法已经被密码分析专家大大削弱,但目前仍然适合大多数人使用,除了那些特别谨慎的人。
关于它们在密码中的使用,主要目的是为了防止原始密码被发现。所以md5碰撞很容易生成其实没什么大不了,因为碰撞只是产生一个与原始密码有相同md5哈希值的替代密码,并不会泄露原始密码。
重要提示:
你的版本缺少一个重要的部分:盐值。盐值是一个随机字符串,它会和原始密码连接在一起生成哈希值,然后再和哈希值一起存储。这样做的目的是确保使用相同密码的用户不会得到相同的存储哈希值。
import random
print('Username: ' + os.environ['USER'])
passwd = getpass('Password: ')
salt = ''.join(random.choice('BCDFGHJKLMNPQRSTVWXYZ') for range(4))
h = hashlib.md5()
h.update(salt)
h.update(passwd.encode())
passwd_encrypt = salt + h.hexdigest()
然后你可以通过重新使用存储的盐值来验证密码:
passwd = getpass('Password: ')
salt = passwd_encrypt[:4]
h = hashlib.md5()
h.update(salt)
h.update(passwd.encode())
if passwd_encrypt != salt + h.hexdigest():
raise LoginFailed()