程式設計師之網路安全系列(二):如何安全儲存使用者密碼及雜湊演算法
系列目錄:
前言
在很多網站的早期,甚至是現在仍然有一些網站,當你點選忘記密碼功能時,你的郵箱會收到一封郵件,然後裡面赫然寫著你的密碼,很多普通使用者還會覺得慶幸,總算是找回來了,殊不知,這是多麼可怕地一件事,說明了網站是“幾乎是”明文儲存你的密碼,一旦資料使用者資料洩露或者被拖庫,那麼使用者密碼將赤裸裸的暴露了,想想之前幾次網際網路密碼洩露事件。
那麼如何解決呢?
加密
為了不讓密碼明文儲存,我們需要對密碼進行加密,這樣即使資料庫使用者密碼暴露,也是加密後的。但是如何讓加密後的資料難以解密呢?我們現在比較流行的做法就是把密碼進行Hash儲存。
Hash
雜湊演算法將任意長度的二進位制值對映為較短的固定長度的二進位制值,這個小的二進位制值稱為雜湊值。雜湊值是一段資料唯一且極其緊湊的數值表示形式. 典型的雜湊演算法包括 MD2、MD4、MD5 和 SHA-1
Hash演算法是給訊息生成摘要,那麼什麼是摘要呢?
舉個例子:
比如你給你女朋友寫了一封郵件,確保沒被人改過,你可以生成這樣一份摘要 “第50個字是我,第100個字是愛, 第998個字是你”,那麼你女朋友收到這個摘要,檢查一下你的郵件就可以了。
Hash演算法有兩個非常主要的特徵:
- 不能通過摘要來反推出原文
- 原文的非常細小的改動,都會引起Hash結果的非常大的變化
因此,這個比較適合用來儲存使用者密碼,因為不能反推出使用者密碼,Hash結果一致就證明原文一致,我們來用Ruby程式碼試一下上面的第二點 (MD5是一種常用的Hash演算法)
2.2.3 :003 > require 'digest/md5.so' => true 2.2.3 :004 > puts Digest::MD5.hexdigest('I love you') e4f58a805a6e1fd0f6bef58c86f9ceb3 => nil 2.2.3 :005 > puts Digest::MD5.hexdigest('I love you!') 690a8cda8894e37a6fff4d1790d53b33 => nil 2.2.3 :006 > puts Digest::MD5.hexdigest('I love you !') b2c63c3ca6019cff3bad64fcfa807361 => nil 2.2.3 :007 > puts Digest::MD5.hexdigest('I love you') e4f58a805a6e1fd0f6bef58c86f9ceb3 => nil 2.2.3 :008 >
那麼我們在使用MD5儲存密碼時候的驗證流程是什麼呢?
- 使用者註冊時,把使用者密碼是MD5(password)後儲存到資料庫。
- 使用者輸入使用者名稱和密碼
- 伺服器從資料庫查詢使用者名稱
- 如果有這個使用者,A=MD5(input password), B=Database password
- 如果A==B, 那麼說明使用者密碼輸入正確,如果不相等,使用者輸入錯誤。
為什麼Hash(MD5)後仍然不夠安全?
窮舉
但是,如果你認為就只是這樣密碼就不會被人知道,那麼就不對了,這只是比明文更安全,為什麼?
因為,大部分人的密碼都非常簡單,當拿到MD5的密碼後,攻擊者也可以通過比對的方式,比如你的密碼是4218
2.2.3 :008 > puts Digest::MD5.hexdigest('4218')
d278df4919453195d221030324127a0e
那麼攻擊者可以把1到4218個數字都MD5一下,然後和你密碼的MD5對比一下,就知道你原密碼是什麼了。
曾經我的密碼箱密碼忘了,我把鎖給撬了,後來我才想起可以用窮舉法,最多就999次不就打開了?那麼問題來了,你的密碼箱還安全嗎?
彩虹表
除了窮舉法外,由於之前的密碼洩露,那麼攻擊者們,手上都有大量的彩虹表,比如"I love you",生日等等,這個表儲存了這些原值以及MD5後的值,那麼使用時直接從已有庫裡就可以查出來對應的密碼。
加鹽 Salt
那麼,由於簡單的對密碼進行Hash演算法不夠安全,那麼我們就可以對密碼加Salt,比如密碼是"I love you", 雖然彩虹表裡有這條資料,但是如果加上"安紅我愛你",這樣MD5結果就大不一樣.
jacks-MacBook-Air:~ jack$ irb
2.2.3 :001 > require 'digest/md5.so'
=> true
2.2.3 :002 > puts Digest::MD5.hexdigest('I love you')
e4f58a805a6e1fd0f6bef58c86f9ceb3
=> nil
2.2.3 :003 > puts Digest::MD5.hexdigest('I love you安紅我愛你')
b10d890bf46b1a045eb99af5d43c7b13
=> nil
2.2.3 :004 > puts Digest::MD5.hexdigest('I dont love you')
c82294c9a7b6e4a372ad25ed4d6011c9
=> nil
2.2.3 :005 > puts Digest::MD5.hexdigest('I dont love you安紅我愛你')
dce67bcdfdf007445dd4a2c2dc3d29c1
=> nil
2.2.3 :006 >
如此一來,因為攻擊者很難猜到“安紅我愛你”,那麼自然彩虹表裡是沒有的,當然我建議你在實際專案中不要使用"安紅我愛你",你應該使用一個連你自己都猜不到的較長的字串。
加鹽了,就安全了嗎?
實際上,加鹽並不能100%保證安全,假如有人洩露了你的Salt呢?實際上通過反編譯程式很容易可以拿到這個,由於WEB程式一般放在WEB伺服器上,那麼就需要保證伺服器不被攻擊,當然這個是運維人員去操心。
為了讓加鹽更安全,一般情況下我們可以使用一個“鹽+鹽”,也就是為每個使用者儲存一個"Salt", 然後再使用全域性的鹽,我們可以對使用者的鹽使用自己的加密演算法。那麼程式碼就如下:
if MD5(userInputPpassword+globalsalt+usersalt)===user.databasePassword)
{
login success
}
普通使用者如何做?
由於這個是寫給程式設計師,當然是說在前端使用者註冊時密碼應該如何設定,很簡單,我們要求使用者必須輸入強密碼!但是,我知道很多使用者覺得很煩,這樣你就失掉了一個使用者,但我們需要做一個適當的折中,比如至少有一個大寫字母,小寫字母和數字的組合。
最後
我們來看看解決了之前文章下面例子的什麼問題。
假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去
- 如何保證隔壁老王不能看到情書內容?(保密性)
- 如何保證隔壁老王不修改情書的內容?(完整性)
- 如何保證隔壁老王不冒充明明?(身份認證)
- 如何保證明明不能否認情書是自己寫的?(來源的不可否認)
通過了解hash演算法,"明明" 就有辦法讓麗麗知道信的內容沒有修改,他可以對郵件進行Hash生成郵件的摘要,然後讓"隔壁的李叔叔"把摘要送給麗麗,麗麗拿到郵件的摘要後,把郵件內容也Hash一下,然後把結果和"隔壁的李叔叔"給的摘要對比一下,然後通過比較結果就知道郵件有沒有被"隔壁的王叔叔"更改過了。
相關推薦
程式設計師之網路安全系列(二):如何安全儲存使用者密碼及雜湊演算法
系列目錄: 前言 在很多網站的早期,甚至是現在仍然有一些網站,當你點選忘記密碼功能時,你的郵箱會收到一封郵件,然後裡面赫然寫著你的密碼,很多普通使用者還會覺得慶幸,總算是找回來了,殊不知,這是多麼可怕地一件事,說明了網站是“幾乎是”明文儲存你的密碼,一旦資料使用者資料洩露或者被拖庫,那麼使用者密碼將赤裸裸
Web安全系列(二):XSS 攻擊進階(初探 XSS Payload)
什麼是 XSS Payload 上一章我談到了 XSS 攻擊的幾種分類以及形成的攻擊的原理,並舉了一些淺顯的例子,接下來,我就闡述什麼叫做 XSS Payload 以及從攻擊者的角度來初探 XSS 攻擊的威力。 在黑客 XSS 攻擊成功之後,攻擊者能夠對使用者當前瀏覽的頁面植入各種惡意指令碼,通過惡意指令碼來
程式設計師之網路安全系列(一):為什麼要關注網路安全?
系列目錄: 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 前言 大家都知道最近幾年鬧的沸
程式設計師之網路安全系列(六):動態密碼
系列目錄 前文回顧 程式設計師之網路安全系列(五):數字證書以及12306的證書問題 我們使用了數字證書,確保了對方的公鑰身份,也就是網際網路中確定了要訪問的網站就是你要訪問的網站。 但是我們如何確定要訪問這個網站的使用者就是要訪問的使用者呢? 對銀行來說需要確保“敏捷的水”登入銀行時,必須是"敏捷
程式設計師之網路安全系列(五):數字證書以及12306的證書問題
系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 中間人攻擊 上面
程式設計師之網路安全系列(四):資料加密之非對稱祕鑰
系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 但是上面的問題是明
程式設計師之網路安全系列(三):資料加密之對稱加密演算法
系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 上一節,我們使用了Ha
容器開啟數據服務之旅系列(二):Kubernetes如何助力Spark大數據分析
容器 控制臺 摘要: 容器開啟數據服務之旅系列(二):Kubernetes如何助力Spark大數據分析 (二):Kubernetes如何助力Spark大數據分析 概述 本文為大家介紹一種容器化的數據服務Spark + OSS on ACK,允許Spark分布式計算節點對阿裏雲OSS對象存儲的直接訪問。
node總結之檔案操作系列(二)
接著上一篇部落格來啊,咱們繼續看非同步模式下關閉檔案的語法格式: fs.close(fd, callback) 引數描述如下: fd - 通過 fs.open() 方法返回的檔案描述符。 callback - 回撥函式,沒有引數。 例項如下: var
java程式設計師菜鳥進階(二)oracle基礎詳解(二)oracle查詢語句和資料排序
本文所以練習都是基於oracle自帶提供的一個數據庫進行的。資料庫中包含員工表emp。部門資訊表dept。員工工資工總表下面是三個表的表結構:一:基本查詢語句1.最簡單的查詢所有列語句Select * from emp;2.查詢指定列表的查詢語句Select empno ,e
ASP.NET Web API(二):安全驗證之使用HTTP基本認證
在前一篇文章ASP.NET Web API(一):使用初探,GET和POST資料中,我們初步接觸了微軟的REST API: Web API。 我們在接觸了Web API的後就立馬發現了有安全驗證的需求,所以這篇文章我們先來討論下安全驗證一個最簡單的方法:使用HTTP基本
微信小程式開發之微信支付(二)獲取openID
openID是微信使用者的唯一標識。我們通過從前端傳來的 code 呼叫登入API獲取openID和session_key。這個過程想必已經有很多例子。接下來我會介紹一種通過現成的SDK來實現。首先需要大家熟悉它。在下面的講解中,我會指出所用到的類和方法 cn.binaryw
linux網路程式設計之TCP/IP基礎(二):利用ARP和ICMP協議解釋ping命令
一、MTU 乙太網和IEEE 802.3對資料幀的長度都有限制,其最大值分別是1500和1492位元組,將這個限制稱作最大傳輸單元(MTU,Maximum Transmission Unit)。如果I
程式設計師滴無奈生活記(二)
也許有一天,你會看到這篇部落格,我想那時又是一段美好的回憶吧! ——致自己 好久沒更新部落格了,準確的說自己最近學的東西太少了,總在反思一件事,想當年我為什麼走上學Android的路,身邊的小夥伴前兩天叫我一起搞遊戲開發,唉!想想都是淚啊,想當年我們一起學An
程式設計師談戀愛的故事(二)
後來,我們還是分手了。 年初分的。 我現在回到了美麗的大雲南。我在創業的路上越走越遠。 她和我說,要結婚,就必須有車有房。我說,沒有問題。但我要慢慢掙,我在公司,半年就混到了部門主管,但是每個月拿著那微薄的工資,感覺離買車買房好遠好遠。我家裡是沒有錢支援我的,我爸媽都是
程式設計師必會技能系列(2)git中merge和rebase比較-3
git中有兩個合併分支的方法,一個是git merge,另一個是git rebase。 一、git merge 講解 1、畫圖講解git merge 用merge合併分支時不會改變歷史(通俗的說就是commit號不會變)。在git中merge會創造一個
程式設計師 之 一路走來(1)
在程式設計師這條路上累了你就聽聽歌吧送給自己一首默默忍淚向上遊幸運不肯輕招手我要艱苦奮鬥努力不會有極限若遇失敗再重頭現實欺弄不擔憂我要跟它決鬥挺著胸對抗命運用力握實我拳頭成功不會驟然降喝采聲不想白白承受求能用心求能用功求能做好鼓手像怒海的小孤舟冷雨悽風繼續有我願那苦痛變力量默
程式設計師面試的一些知識點(二)
1.一個好的設計所具備的特徵有哪些?全面考慮,元件獨立,容錯機制,異常處理。高內聚,低耦合。 2.測試全面指的是:單元測試,整合測試,系統測試(效能測試,安全測試,易用性測試,相容性測試)。 3.將記憶體地址編碼擴大到外圍裝置上的編碼方式為?暫時不會 4浮點運算指令屬於算術
“造輪運動”之 ORM框架系列(二)~ 說說我心目中的ORM框架
ORM概念解析 首先梳理一下ORM的概念,ORM的全拼是Object Relation Mapping (物件關係對映),其中Object就是面嚮物件語言中的物件,本文使用的是c#語言,所以就是.net物件;Relation Mapping則是關係對映,在資料庫的系統中指的就是.net物件與資
前端程式設計師學好算法系列(一)陣列
前端程式設計師怎麼才能學好演算法呢?目前演算法優秀的視訊集中在c++,java,python,本人通過幾個月專心看c++的視訊掌握了演算法的基本思路,都翻譯成前端程式碼一一寫出來,從真題到思維全面提升演算法思維面對演算法面試,不畏懼 二分查詢法O(logn)尋找陣列中的最大/最小值O(N)歸併排序演算法 O(