(一):为什么要用哈希函数来加密密码:
1、如果开发者需要保存密码(比如网站用户的密码),要考虑如何保护这些密码数据,网站用户密码的泄露是一件非常严重的事情,容易引起用户恐慌,所以在安全方面是重中之重,直接将密码以明文写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码。
2、解决的办法是将密码加密后再存储进数据库,比较常用的加密方法是使用哈希函数(Hash Function)。哈希函数的具体定义,网上和相关书籍中有很多,简单地说,它的特性如下:
(1)原始密码经哈希函数计算后得到一个哈希值;
(2)改变原始密码,哈希函数计算出的哈希值也会相应改变;
(3) 同样的密码,哈希值也是相同的;
(4) 哈希函数是单向、不可逆的。也就是说从哈希值,你无法推算出原始的密码是多少;
有了哈希函数,我们就可以将密码的哈希值存储进数据库。用户登录网站的时候,我们可以检验用户输入密码的哈希值是否与数据库中的哈希值相同。由于哈希函数是不可逆的,即使有人打开了数据库,也无法看到用户的密码是多少。
注:但不意味着存储经过哈希函数加密后的密码就是绝对的安全!
(二):几种常见的破解密码的方法
简单、常见的破解方式当属字典破解(Dictionary Attack)和暴力破解(Brute Force Attack)方式。
字典破解和暴力破解都是效率比较低的破解方式。如果你知道了数据库中密码的哈希值,你就可以采用一种更高效的破解方式,查表法(Lookup Tables)。还有一些方法,比如逆向查表法(Reverse Lookup Tables)、彩虹表(Rainbow Tables)等,都和查表法大同小异。现在我们来看一下查表法的原理。
查表法不像字典破解和暴力破解那样猜密码,它首先将一些比较常用的密码的哈希值算好,然后建立一张表,当然密码越多,这张表就越大。当你知道某个密码的哈希值时,你只需要在你建立好的表中查找该哈希值,如果找到了,你就知道对应的密码了。
(三):为密码加盐(Salt)
从查表法可以看出,即便是将原始密码加密后的哈希值存储在数据库中依然是不够安全的。那么有什么好的办法来解决这个问题呢?答案是加盐值(salt)。
盐(Salt)是什么?就是一个随机生成的字符串。我们将盐与原始密码连接(concat)在一起(放在前面或后面都可以),然后将concat后的字符串加密。采用这种方式加密密码,查表法就不灵了(因为盐是随机生成的)。
(四):Python3实现哈希加盐实现!
#---------------------------------------------------
# Python3简单密码加盐程序
# 通过随机生成4位salt,与原始密码组合,通过md5加密
#---------------------------------------------------
# 导入哈希md5模块
from hashlib import md5
# 导入随机数模块
from random import Random
# 获取由4位随机大小写字母、数字组成的salt值
def create_salt(length = 4):
salt = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
# 获取chars的最大下标
len_chars = len(chars)-1
random = Random()
for i in range(length):
# 每次随机从chars中抽取一位,拼接成一个salt值
salt += chars[random.randint(0,len_chars)]
return salt
# 获取原始密码+salt的md5值
def create_md5(pwd,salt):
md5_obj = md5()
md5_obj.update((pwd+salt).encode('utf-8'))
return md5_obj.hexdigest()
# 随机密码
pwd = input("请输入密码:")
# 随机生成的4位salt
salt = create_salt()
# 加密后的密码
md5_pwd = create_md5(pwd,salt)
# 输出效果如下
请输入密码:123
密码:123
salt:DY6Z
md5加密后的密码:3861786c18d0edce6dd6d446b9a33625
(五):小结
单单使用哈希函数来为密码加密是不够安全的,需要为密码加盐来提高安全性,盐的长度不能过短,并且盐的产生应该是随机的。