密碼在伺服器一般不能明文儲存,所以這裡就涉及到加密處理的問題。
我們採用hash演算法對密碼進行加密後儲存在資料庫中,
2 nodejs 密碼雜湊方案bcrypt
下面簡單介紹下hash演算法
hash,一般翻譯做「雜湊」,也有直接音譯為「雜湊」的,就是把任意長度的輸入(又叫做預雜湊, pre-image),通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。簡單的說就是一種將任意長度的訊息壓縮到某一固定長度的訊息摘要的函式。具有單向的特點。
這裡我們總結出hash對於我們密碼加密非常有用的兩個特性:
1不可逆,即hash過程過程不可逆,你不可以通過hash後的值得到原值。
2無衝突,你知道乙個值(x),但無法求出另乙個值(y),使這兩個值得hash值相同。
以上性質對於對於密碼加密而言就是
(1)原始密碼經雜湊函式計算後得到乙個雜湊值
(2)改變原始密碼,雜湊函式計算出的雜湊值也會相應改變
(3) 同樣的密碼,雜湊值也是相同的
(4) 雜湊函式是單向、不可逆的。也就是說從雜湊值,你無法推算出原始的密碼是多少
md5:它對輸入仍以512位分組,其輸出是4個32位字的級聯
sha-1 sha256等:它對長度小於264的輸入,產生長度為160bit的雜湊值
密碼中混入一段「隨機」的字串再進行雜湊加密,這個被字串被稱作鹽值。
為什麼要加鹽:同乙個密碼經過雜湊演算法後得到的密碼是一致,攻擊者可以通過建立乙個密碼和雜湊機密後的表的對應關係的表提高破解效率。
如果加鹽,這使得同乙個密碼每次都被加密為完全不同的字串。為了校驗密碼是否正確,我們需要儲存鹽值。通常和密碼雜湊值一起存放在賬戶資料庫中,或者直接存為雜湊字串的一部分。
每次雜湊加密都使用相同的鹽值是很容易犯的乙個錯誤,這個鹽值要麼被硬編碼到程式裡,要麼只在第一次使用時隨機獲得。這樣加鹽的方式是做無用功,因為兩個相同的密碼依然會得到相同的雜湊值。攻擊者仍然可以使用反向查表法對每個值進行字典攻擊,只需要把鹽值應用到每個猜測的密碼上再進行雜湊即可。如果鹽值被硬編碼到某個流行的軟體裡,可以專門為這個軟體製作查詢表和彩虹表,那麼破解它生成的雜湊值就變得很簡單了。
使用者建立賬戶或每次修改密碼時,都應該重新生成新的鹽值進行加密。
**加鹽使攻擊者無法採用特定的查詢表和彩虹表快速破解大量雜湊值,但是卻不能阻止他們使用字典攻擊或暴力攻擊。**高階的顯示卡(gpu)和定製的硬體可以每秒進行數十億次雜湊計算,因此這類攻擊依然可以很高效。為了降低攻擊者的效率,我們可以使用一種叫做金鑰擴充套件的技術。
這種技術的思想就是**把雜湊函式變得很慢,於是即使有著超高效能的gpu或定製硬體,字典攻擊和暴力攻擊也會慢得讓攻擊者無法接受。**最終的目標是把雜湊函式的速度降到足以讓攻擊者望而卻步,但造成的延遲又不至於引起使用者的注意。這裡推薦一種標準演算法:bcrypt。
這類演算法使用乙個安全因子或迭代次數作為引數,這個值決定了雜湊函式會有多慢。對於桌面軟體或者手機軟體,獲取引數最好的辦法就是執行乙個簡短的效能基準測試,找到使雜湊函式大約耗費0.5秒的值。這樣,你的程式就可以盡可能保證安全,而又不影響到使用者體驗。
因為bcrypt採用了一系列各種不同的blowfish加密演算法,並引入了乙個work factor,這個工作因子可以讓你決定這個演算法的代價有多大。因為這些,這個演算法不會因為計算機cpu處理速度變快了,而導致演算法的時間會縮短了。因為,你可以增加work factor來把其效能降下來。
bcrypt到底有多慢?如果和md5一起來比較的話,如果使用值為12的work factor的話,如果加密「cool」的話,bcrypt需要0.3秒,而md5只需要一微秒(百萬分之一秒)。也就是說,前面我們說的那個只需要40秒就可以窮舉完所有的可能的md5編碼的口令的演算法,在使用bcrypt下,需要12年。
來自:如何生成密文
1).首先我們得到的是明文的hash值
2).進行計算獲取md5明文hash值
3).隨機生成加鹽值並插入
4).md5插入加鹽值得到的hash
5).得到最終的密文
如何驗證密碼
得到使用者的密碼雜湊值和對應鹽值
將鹽值混入使用者輸入的密碼,並且使用同樣的雜湊函式進行加密
比較上一步的結果和資料庫儲存的雜湊值是否相同,如果相同那麼密碼正確,反之密碼錯誤
api 說明
bcrypt.
hash
(myplaintextpassword, saltrounds,
function
(err, hash)
);
bcrypt.
compare
(password, encryptpassword,
function
(err, res)
)
sample code:
var bcrypt =
require
('bcrypt');
var password =
"helloworld"
;bcrypt.
hash
(password,10,
function
(err, encryptpassword))}
);bcrypt.
hash
(password,8,
function
(err, encryptpassword1))}
);
輸出
bcrypt password:$2b$08$dmg3epmn3kgobbb/
15yb/or8pnikvwt1c5ftuuiy6shhlvubmi9oq
password is true
bcrypt password:$2b$10$cga8jvxfccx5iwss8hauioiayjkwr45eupd/mmlxt/gr1t7ro1xp2
password is true
關於該模組鹽位置說明,鹽值本身就在 處理後的字串中,我們用於驗證時,模組會提取出鹽值進行驗證。
加密後的字串還可以看的出crypt()版本 和加密輪數
3 參考鏈結
nodejs中的bcryptjs密碼加密
bcryptjs是乙個第三方密碼加密庫,是對原有bcrypt的優化,優點是不需要安裝任何依賴 npmjs位址 npm install bcryptjsvar bcrypt require bcryptjs 生成hash密碼 var bcrypt require bcryptjs var salt b...
使用者密碼到底要怎麼加密儲存?
使用者密碼儲存到資料庫時,以下幾種方式是常見的密碼儲存方式 直接明文儲存,比如使用者設定的密碼是 123456 直接將 123456 儲存在資料庫中,這種是最簡單的儲存方式,也是最不安全的方式。但實際上不少網際網路公司,都可能採取的是這種方式。使用對稱加密演算法來儲存,比如3des aes等演算法,...
golang pbkdf2加密儲存使用者密碼
pbkdf2 password based key derivation function 是乙個用來匯出金鑰的函式,常用於生成加密的密碼。原理是通過 password 和 salt 進行 hash 加密,然後將結果作為 salt 與 password 再進行 hash,多次重複此過程,生成最終的密...