(一):為什么要用哈希函數來加密密碼:
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
(五):小結
單單使用哈希函數來為密碼加密是不夠安全的,需要為密碼加鹽來提高安全性,鹽的長度不能過短,並且鹽的產生應該是隨機的。