本次的越寫越快樂系列為大家?guī)韱蜗蛏⒘泻瘮档姆窒恚簿褪俏覀兘洺Uf的哈希函數的統(tǒng)稱瞬逊,接下來我會通過以下幾個方面來說明單項散列函數的內容。
相關術語
- 單向散列函數(one-way hash function)也稱為信息摘要函數(message digest function)挟秤、哈希函數或者雜湊函數
- 輸入單向散列函數的消息也稱為原像(pre-image)
- 單向散列函數輸出的散列值也稱為消息摘要(message digest)或者指紋(fingrprint)
- 消息的完整性也稱為一致性
什么是單項散列函數
這個文件是不是真的呢
Alice在公司從事軟件開發(fā)工作粘昨。一天晚上垢啼,她的軟件終于完成了,接下來只要把文件從Alice的電腦中復制出來并制作成母盤就可以了张肾。
但是Alice已經很累了芭析,她決定今天晚上早點回家休息,明天再繼續(xù)弄吞瞪。
第二天馁启,Alice來到公司準備把文件從自己的電腦中復制出來,但她突然產生了這樣的疑問:“這個文件和我昨天晚上生產的文件是一樣的嗎?”
Alice的疑問是這樣的——會不會有人操作Alice的計算機惯疙,將文件改寫了呢翠勉?就算沒有人直接來到Alice的座位上,也有可能通過網絡入侵Alice的計算機霉颠《月担或者,也許Alice的計算機感染了病毒蒿偎,造成文件被篡改……在這里朽们,是人文的還是病毒干的并不重要,我們姑且把篡改文件的這個主體稱為“主動攻擊者Mallory”诉位∑锿眩總而言之,Alice需要知道從昨天到今天的這段時間內苍糠,Mallory是否篡改了文件的內容叁丧。
那有沒有什么辦法幫助驗證Alice手上的文件是不是“真的”呢?如果這個文件和昨天晚上生成的文件一模一樣岳瞭,那它就是真的拥娄;但只要有一點點不一樣,哪怕只要一個比特(bit)有所不同寝优、增加或者減少条舔,它就不是真的枫耳。這種“是真的”的性質稱為完整性
乏矾,也稱為一致性
。也就是說這里Alice需要確認的迁杨,是自己手上的文件的完整性钻心。
稍微想一下我們就能找到一種確認文件完整性的簡單方法——在回家之前先把文件復制到一個完全的地方保存起來,第二天在用這個文件工作之前铅协,先將其和事先保存的文件進行對比就可以了捷沸。如果兩者一致,那就說明文件沒有被篡改狐史。
不過這種確認完整性的方法其實是毫無意義的痒给。因為如果可以事先把文件保存在一個安全的地方,那根本就不需要確認完整性骏全,直接用事先保存的文件來工作不就行了嗎苍柏?
此外還有一個效率問題。如果需要確認完整性的文件非常巨大姜贡,那么文件的復制试吁、保存以及比較都將非常耗時。
終于輪到我們的豬腳
單向散列函數
出場了楼咳,就像刑事偵查中獲取指紋一樣熄捍,我們能不能獲取到Alice所生成的文件的“指紋”呢烛恤?如果我們不需要對整個巨大的文件進行對比,只需要對比一個較小的指紋就能夠檢查完整性的話余耽,那該多方便啊缚柏。
什么是單向散列函數
單向散列函數有一個輸入和輸出,其中輸入稱為消息(message)碟贾,輸出稱為散列值(hash value)船惨。單向散列函數可以根據消息的內容計算出散列值,而散列值就可以被用來檢查消息的完整性缕陕。單向散列函數所生成的散列值粱锐,就相當于消息的“指紋”。
要點:消息的長度沒有限制扛邑,生成的散列值有固定長度(bit)怜浅。
單向散列函數的性質
- 根據任意長度的消息計算出固定長度的散列值
首先,單向散列函數的輸入必須是任意長度的消息蔬崩。其次恶座,無論輸入多長的消息,單向散列函數必須能夠生成長度很短的散列值沥阳。從使用方便的角度看跨琳,散列值的長度最好是短且固定的。 - 能夠快速計算出散列值
計算散列值所花費的時間必須要短桐罕。 - 消息不同散列值也不同
為了能夠確認完整性脉让,消息中哪怕只有1比特的改變,也必須有很高的概率產生不同的散列值功炮。 - 具備單向性
單向散列函數必須具備單向性溅潜。單向性指的是無法通過散列值反計算出消息的性質。根據消息很容易計算出散列值薪伏,但是根據散列值幾乎很難推斷出消息的內容滚澜。
單向散列函數的實際應用
檢測軟件是否被篡改
我們可以使用單向散列函數來確認自己下載的軟件是否被篡改。我們的具體操作步驟如下:
- 用戶自行下載軟件到本地
- 計算該軟件的散列值
- 比對官方網站上公布的散列值和自行計算的散列值
- 根據比對結果來判斷自己下載的文件是否是安全的軟件嫁怀,有沒有被惡意篡改
基于口令的加密
單向散列函數也被用于基于口令的加密(Password Based Encryption设捐,PBE)。PBE的原理是將口令和鹽(salt - 通過偽隨機數生成器產生的隨機值)混合計算其散列值塘淑,然后將這個散列值用作加密的密鑰萝招。
消息認證碼
使用單向散列函數可以構造消息認證碼。消息認證碼是將“發(fā)送者和接收者之間的共享密鑰”和“消息”進行混合后計算出的散列值朴爬。使用消息認證碼可以檢測并防止通信過程中的錯誤即寒、篡改以及偽裝。
數字簽名
在進行數字簽名時也會使用單向散列函數。數字簽名是現(xiàn)實社會中的簽名和蓋章這樣的行為在數字世界中的實現(xiàn)母赵。數字簽名的處理過程非常耗時逸爵,因此一般不會對整個消息內容直接施加數字簽名,而是先通過單向散列函數計算出消息的散列值,然后再對對散列值施加數字簽名。
偽隨機數生成器
使用單向散列函數可以構造偽隨機數生成器坪哄。密碼技術中所使用的隨機數需要具備“事實上不可能根據過去的隨機數列預測未來的隨機數列”這樣的性質捎稚。為了保證不可預測性姻氨,可以利用單向散列函數的單向性。
一次性口令
使用單向散列函數可以構造一次性口令(one-time password)。一次性口令經常被用于服務器對客戶端的合法性認證。在這種方式中瓷胧,通過單向散列函數可以保證口令只在通信鏈路上傳送一次(one-time),因此即使竊聽者竊取了口令棚愤,也無法使用搓萧。
單向散列函數的具體例子
MD系列
MD5(Message Digest 消息摘要 5)也就是Rivest提出的針對MD4的改進版本,它能夠產生128比特的散列值(RFC1321)[https://www.rfc-editor.org/rfc/rfc1321.txt]宛畦。MD5的強抗碰撞性以及被攻破瘸洛,也就是說現(xiàn)在已經能夠產生相同散列值得兩條不同的消息。
SHA系列
SHA-1是由NIST(美國國家標準技術研究所)設計的一種能夠產生160比特的散列值的單向散列函數次和。
1993年被作為作為美國聯(lián)邦信息處理標準規(guī)格(FIPS PUB 180)發(fā)布的是SHA(安全散列算法)反肋。
1995年發(fā)布的修訂版FIPS PUB 180-1稱為SHA-1。
SHA-224踏施、SHA-256石蔗、SHA-384和SHA-512是目前NIST制定的SHA-2的版本,SHA后面的數字代表消息通過單向散列函數生成的散列值的長度(bit-比特)读规。
下面的表格給出目前6個版本的SHA-2標準的簡要情況:
名稱 | 輸出長度(bit) | 備注 |
---|---|---|
SHA-224 | 224 | 將SHA-256的結果截掉32比特 |
SHA-256 | 256 | |
SHA-512/224 | 224 | 將SHA-512的結果截掉288比特 |
SHA-512/256 | 256 | 將SHA-256的結果截掉256比特 |
SHA-384 | 384 | 將SHA-256的結果截掉128比特 |
SHA-512 | 512 |
在2005年SHA-1的強抗碰撞性被攻破的背景下抓督,NIST開始著手制定用于取代SHA-1的下一代單向散列函數SHA-3燃少。Keccak的算法最終成為了SHA-3的新標準束亏。Keccak的設計者之一Gilles Van Assche在GitHub上發(fā)布了一款名為Keccak Tools的軟件。
RIPEMD-160
RIPEMD-160是于1996年由Hans Dobbertin阵具、Antoon Bosselaers和Bart Preneel設計的一種能夠產生160比特的散列值的單向散列函數碍遍。RIPEMD-160是歐盟RIPE項目所設計的RIPEMD單向散列函數的修訂版。這一系列額函數還包括RIPEMD-128阳液、RIPEMD-256怕敬、RIPEMD-320等其他一些版本。RIPEMD的強抗碰撞性已經于2004年被攻破帘皿,但RIPEMD-160還尚未被攻破东跪。
比特幣中使用的就是RIPEMD-160。
應該使用哪些單向散列函數
MD5 - 不建議使用
SHA-1 - 不建議使用
SHA-2
- 建議使用
SHA-3
- 建議使用
單向散列函數無法解決的問題
使用單向散列函數可以實現(xiàn)完整性的檢查,也就是說單向散列函數能夠辨別出“篡改”虽填,但無法辨別出“偽裝”丁恭。
總結
通過對《圖解密碼技術》第七章節(jié)的學習,我們知道了單向散列函數的概念斋日、使用場景以及為什么要使用單向散列函數牲览,那么接下來我們就要看看在具體的編程語言中是如何實現(xiàn)單向散列函數的,那么接下來我有機會會為大家繼續(xù)分享單向散列函數的有關內容恶守,我相信密碼學不是那么復雜第献,只是我們的認知有限,自認為目前流行的區(qū)塊鏈技術使用了哪些高深的技術兔港,使用了哪些不那么通俗易懂的術語庸毫,當然書中還探討了一些單向散列函數的碰撞性問題、SHA-3的選拔過程衫樊、Keccak的內部狀態(tài)和Keccak函數的實現(xiàn)步驟岔绸,這些內容想要一口氣消化那是不可能完成的任務,除非你對密碼學底層實現(xiàn)技術有特別深入的研究橡伞,那么我建議你熟悉常見的單向散列函數的使用場景盒揉、基本原理和使用步驟就足夠了。當然作為一個區(qū)塊鏈技術的愛好者來說兑徘,這些基本知識是必須要知道并且熟練使用的刚盈,我相信你的努力不會白費,我更相信你走過的每一步都算數挂脑,我更知道有無數的007戰(zhàn)友都在支持我們去探索不一樣的人生和進化藕漱,要是我的文章對你有所啟發(fā),那將是我莫大的榮幸崭闲。