1. 前言
在众多的安全机制中,密码哈希常常起到非常重要的作用。在传输信息的过程中,为了防止密码的泄露,我们往往会把明文的密码进行哈希处理,再传输哈希值。而接收方在验证密码时,只需对输入的密码进行哈希处理,然后与传输的哈希值进行比较即可。
本文将介绍如何在Python中进行密码的哈希处理,以提高密码的安全性。
2. 密码哈希简介
哈希就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变成固定长度的输出,该输出就是哈希值。
哈希函数的基本要求:
从哈希值不能反向推导出原始输入。
对于不同的输入,尽可能地产生不同的哈希值。
在密码学中,为了保障密码的安全性,我们通常使用密码学哈希函数进行密码哈希。密码学哈希函数是一种单向的、不可逆的加密算法,最典型的应用是对于一个任意长度的消息(明文),通过哈希算法处理成一定长度的消息摘要(哈希值),是一种在保证通信安全的基础上,尽量减少信息传输量的方案。
3. Python中的哈希方法
Python中有许多库支持哈希算法,常用的有hashlib和cryptography模块。
3.1 hashlib模块
hashlib模块包含了一系列用于加密的哈希算法,比如SHA1、SHA224、SHA256、SHA384、SHA512、MD5等等。
下面是使用hashlib中的md5进行密码哈希的例子:
import hashlib
def hash_password(password):
hashlib_md5 = hashlib.md5()
hashlib_md5.update(password.encode('utf-8'))
return hashlib_md5.hexdigest()
password = '123456'
hashed_password = hash_password(password)
print(hashed_password)
运行结果如下:
e10adc3949ba59abbe56e057f20f883e
可以看到,使用md5对密码进行哈希处理后,得到了长度为32的哈希值。
然而,根据哈希值很容易推算出原始密码,因此使用md5等哈希算法已经不再被安全的认为是一种好的哈希方式。
3.2 cryptography模块
cryptography模块是一个用于加密、解密和密码学的Python库。
下面是使用cryptography中的Bcrypt进行密码哈希的例子:
import bcrypt
def hash_password(password):
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed_password.decode('utf-8')
password = '123456'
hashed_password = hash_password(password)
print(hashed_password)
运行结果如下:
$2b$12$ytAvJg3ZJcgY9bJA5HVxuuLYgepFqO5THyhRvOGAhOJ3xsKoI8wOa
可以看到,使用Bcrypt对密码进行哈希处理后,得到了长度为60的哈希值。
Bcrypt是一种基于Blowfish算法的密码哈希函数,这种哈希函数专为密码存储而设计,在哈希的过程中,它将密码与一个随机数(盐值)进行结合,并且使用大量的计算和内存操作来使密码更难以被破解。
4. 哈希值的存储与验证
在进行密码哈希处理后,我们需要将哈希值存储在数据库中供之后的验证使用。
4.1 填充哈希值的存储
将哈希值直接存储在数据库中存在着不少的安全隐患,因为在数据库被盗的情况下,攻击者可以直接获得用户的密码。因此,通常我们会使用填充哈希值存储方式来增强密码的安全性。
填充哈希值存储方式是指,在存储用户的哈希值时,不仅要存储哈希值本身,还要加入一些额外的信息,以提高哈希值被破解的难度。
比如,我们可以在哈希值中加入一个随机数,这个随机数被称为哈希盐(Hash Salt),通过使用哈希盐,可以在很大程度上提高密码哈希后的安全性。
下面是使用cryptography的Bcrypt进行密码哈希和存储的例子:
import bcrypt
def hash_password(password):
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed_password.decode('utf-8'), salt.decode('utf-8')
def verify_password(password, hashed_password, salt):
return bcrypt.checkpw(password.encode('utf-8'), (salt+hashed_password).encode('utf-8'))
password = '123456'
hashed_password, salt = hash_password(password)
if verify_password(password, hashed_password, salt):
print('密码验证通过!')
else:
print('密码验证失败!')
运行结果如下:
密码验证通过!
在存储哈希值时,我们将哈希盐和哈希值进行合并,并且在验证密码时也需要对哈希盐进行一起指定,并且放到哈希值前面,这样可以在验证密码时将哈希盐和哈希值分离出来进行验证。
4.2 使用随机数对哈希值进行多次处理
通过多次哈希处理,可以有效的增加密码被破解的难度。在哈希处理中,每多进行一次哈希,就可以使破解密码所需要的时间增加几倍。
下面是使用bcrypt进行密码哈希和存储,并且进行多次哈希处理的例子:
import bcrypt
def hash_password(password):
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
for i in range(5):
hashed_password = bcrypt.hashpw(hashed_password, salt)
return hashed_password.decode('utf-8'), salt.decode('utf-8')
def verify_password(password, hashed_password, salt):
temp_hashed_password = hashed_password
for i in range(5):
temp_hashed_password = bcrypt.hashpw(temp_hashed_password, salt.encode('utf-8'))
return bcrypt.checkpw(password.encode('utf-8'), (salt+temp_hashed_password).encode('utf-8'))
password = '123456'
hashed_password, salt = hash_password(password)
if verify_password(password, hashed_password, salt):
print('密码验证通过!')
else:
print('密码验证失败!')
运行结果如下:
密码验证通过!
可以看到,进行多次哈希处理后,破解密码所需要的时间显著增加。
5. 总结
哈希是一种常用的加密方式,常用于密码的传输和存储中。Python中提供了多种哈希算法,其中常用的有hashlib和cryptography模块。
在进行哈希处理时,为了提高密码的安全性,我们可以使用填充哈希值的方式,并且对哈希值进行多次处理。
在进行密码哈希的同时,也需要注意密码的传输与存储安全,避免密码被攻击者获取。