密码学之前后向安全性
本文將討論密碼學中的 前向安全性(Forward Security) 與 后向安全性(Backward Security) ,希望讀完本文后,你再也不會混淆這兩個概念。
在開始本文之前,希望你有如下預備知識:
- 密碼學(Cryptography)是一門什么樣的學科?
- 單向函數(One Way Function)是什么?有哪些例子?
- 密碼算法與密鑰是什么?敵手(Adversary)在密碼學中是一個怎樣的概念?
單向函數與密碼算法
現代密碼學的基石:偽隨機性
Pseudorandomness,即偽隨機性,是一個現代密碼算法必須要具備的性質,因為從反面考慮,如果你設計的密碼算法都做不到「看起來」是隨機的,那豈不是很容易就被攻破了?
當然,偽隨機性在數學上有著更嚴格的定義與論證,在密碼學中也有更深厚的歷史背景(比如其實是姚期智院士率先給出的偽隨機性正式定義[1])。偽隨機作為現代密碼學的核心要素,如何更好地實現它一直是許多科學家追逐的目標,比如采用物理的隨機熵源(真隨機數發生器),或者使用一個秘密的隨機種子(密鑰)等等。一個算法的根基如果不具備良好的偽隨機性,Rivest也不能打包票對你說“哦我的老伙計,試試這個RSA吧,它真的很棒”。
在現代密碼算法中,偽隨機性可以由偽隨機數發生器(PseudoRandom Number Generator,PRNG)來提供。這就是說,要設計一個具備偽隨機性的密碼算法,你可以先明確怎么得到一個PRNG。因此,PRNG這個部件的好壞,將直接決定了算法是否足夠安全。PRNG在現代密碼學語義中的定義如下:
令GGG為一多項式時間算法,其輸入為s∈{0,1}ns\in \{0, 1\}^{n}s∈{0,1}n,即為一長度為nnn的01比特串,輸出的長度記作l(n)l(n)l(n);其中,l(?)l(\cdot )l(?)也為一多項式時間算法,但與GGG不同的是,l(n)l(n)l(n)只是表示是nnn的多項式界下的一個值,l(?)l(\cdot )l(?)可以等于n2n^{2}n2,也可以等于nnn,只要是多項式界內的即可。若G為一PRNG,則應同時滿足如下兩個條件:
∣Pr[A(r)=1]?Pr[A(G(s))=1]∣≤?|\mathrm{Pr}[\mathcal{A}(r)=1] - \mathrm{Pr}[\mathcal{A}(G(s))=1]| \le \epsilon∣Pr[A(r)=1]?Pr[A(G(s))=1]∣≤?
其中,rrr為一真隨機比特串(不用管它從哪來的),而G(s)G(s)G(s)即為GGG的輸出,為一偽隨機比特串. 而A(r)=1\mathcal{A}(r)=1A(r)=1與A(G(s))=1\mathcal{A}(G(s))=1A(G(s))=1分別表示敵手A\mathcal{A}A能正確區分出所給比特串是真隨機串還是偽隨機串。
因此,條件2表明敵手A\mathcal{A}A面對GGG的輸出時,只能以一個可忽略的、極小的概率將其與真隨機串區分開來,這保證了每個PRNG的輸出都會足夠貼近真實的隨機輸出。而對于條件1,如果我們先假設l(n)≤nl(n) \le nl(n)≤n,那這意味著輸入與輸出都不一定能滿足雙射的條件,即PRNG的一個輸出甚至可能對應著多個輸入。由此,這樣的PRNG很容易就被攻擊者猜解碰撞出來了;因此如果令l(n)>nl(n) > nl(n)>n,如l(n)=2nl(n)=2nl(n)=2n,那么一個輸入sss則平均對應著2n=22n/2n2^{n}=2^{2n}/2^{n}2n=22n/2n個PRNG輸出,也就是這是一種非常稀疏的映射關系,這種「擴展性」保證了采取窮舉手段從PRNG的輸出空間來進行碰撞是困難的。
現在我們有了偽隨機性這把(簡陋)的螺絲刀,還能造出更好的工具嗎?
單向函數
首先便是直接由偽隨機性抽象而來的、更加直觀的,但也非常重要的性質:One-Wayness,即單向性。顧名思義,再結合PRNG的定義,相信大家此時對單向性及單向函數(One-Wayness Function, OWF)也會有這樣一個模糊理解:
給函數一個xxx,可以跟容易算出對應的函數值yyy,但是對于函數值yyy,很難逆推得到原來的xxx
這種理解其實已經非常接近單向函數的正式定義了,如下所示:
一個函數f若稱為單向函數,則應滿足如下兩個條件:
Pr[D(f(x))∈f?1(f(x))]≤?Pr[D(f(x)) \in f^{-1}(f(x))] \le \epsilon Pr[D(f(x))∈f?1(f(x))]≤?
其中,xxx的選取是從{0,1}n\{0,1\}^{n}{0,1}n中隨機均勻采樣。在上述定義中,難以求逆這一性質只需要在輸入是均勻選取的這一條件下成立即可,即對于極個別的輸出點,攻擊者還是有可能還原其對應的輸入的。在某些比較極端的定義里,難以求逆這一性質甚至只要求在輸入xxx足夠長時才滿足。
此時你可能會說,既然一個單向函數是容易計算的,那對于一個特定的輸出yyy,那我為什么不能試著遍歷所有xix_{i}xi?,從而找到f(x?)=yf(x^{*})=yf(x?)=y?沒錯,任何單向函數在給出足夠時間和計算資源的條件下,都是可求逆的;但不要忘記條件2中面向的是多項式時間算法,對于那些指更高級的攻擊算法,單向函數可能真的一下就被攻破了。因此,條件2所謂的難以求逆,實際上是難以「高效」求逆。
實際上,任意一個PRNG都可看作是一個單向函數 [2],而要證明這一點,即證「對于一個PRNG算法 G\mathcal{G}G,如果存在敵手D\mathcal{D}D能以不可忽略的概率對 G\mathcal{G}G的輸出結果求逆,那么存在一敵手D′\mathcal{D}^{'}D′也能以不可忽略的概率分辨G\mathcal{G}G的輸出與真隨機串」。一般而言這種證明采取“安全性歸約”的方法即可,不過這和本文內容無關。總之,基于PRNG可以構造出單向函數,而有了單向函數這個「高級扳手」,我們就可以造出更方便的工具了,比如大名鼎鼎的(密碼學安全的)哈希函數。
阿克琉斯之踵:密鑰的管理
PRNG與OWF由于其簡潔但重要的計算性質,常被用于生成密碼算法的密鑰,而PRNG這種「看起來」隨機的特點,正是方便我們生成一些別人不想預測出的敏感信息。另外,OWF則能幫助我們為已有密鑰提供一個「陷門」(Trapdoor),陷門的輸出(通常為OWF的輸出)可以作為新密鑰、或者某個公開校驗值等等。
二者的配合讓一個系統中,密鑰的在線更新成為了可能。如果一個OWF提供的偽隨機性足夠好,那我們是不是可以用它源源不斷地生成新密鑰呢?當然可以!
如上圖所示,系統管理員可以使用當前密鑰KiK_{i}Ki?、當前時間戳tit_{i}ti?以及一個鹽值Salt(如0x12345),在MD5這一哈希函數的幫助下源源不斷的迭代出新密鑰ki+1=MD5(ki∣∣tI∣∣Salt)k_{i + 1} = \mathrm{MD5}( k_{i} || t_{I} || Salt)ki+1?=MD5(ki?∣∣tI?∣∣Salt)。當然,MD5可以替換為其他常見的、更安全的哈希函數。
可是,隨著密碼分析技術的不斷增強,原來認為安全的MD5目前來看也不那么安全了,原本的單向函數也不再那么單向了。而管理員此時還覺得:
反正我密鑰一直都在給你們更新,況且MD5也沒那么容易被攻擊,這個方案又不是不能用😄
管理員笑了,黑客也笑了。
這種做法有一個無法忽視的風險在于,如果系統中某些用戶喜新厭舊,他只會好好保管手頭上的新密鑰,那么若攻擊者獲取了他曾經的密鑰,目前的系統或目前的密鑰還是安全的嗎?另外,如果攻擊者獲取了他目前的密鑰,系統中的歷史狀態或歷史密鑰還會是安全的嗎?
這樣的密鑰管理問題一直是許多密碼學專家的心頭之恨:“明明這算法本身已經天衣無縫了,攻擊者還是能從一些奇怪的地方拿到密鑰”,而根據Kerkoff準則,一旦密鑰不安全了,那整個密碼系統也就不安全了。因此,密鑰管理就像是一個信息系統的阿克琉斯之踵一樣,只要攻擊者擁有足夠精妙的攻擊方法,他便能一擊致命。
前向安全性 與 后向安全性
鋪墊了那么多,終于要介紹正題了。
直覺上的判斷
如果你直接Google “Forward/Backward Security”,你很可能會看到兩種截然相反的定義:
版本一[3]:
- 前 向安全性是指,當前密鑰被攻擊者獲取后,歷史 的密鑰仍然是安全的
- 后 向安全性是指,當前密鑰被攻擊者獲取后,未來 的密鑰仍然是安全的
版本二[4]:
- 前 向安全性是指,當前密鑰被攻擊者獲取后,未來的密鑰仍然是安全的
- 后 向安全性是指,當前密鑰被攻擊者獲取后,歷史 的密鑰仍然是安全的
直覺上理解,可能有的讀者在看到「前向」一詞時,腦海里自然而然會浮現出一根時間軸,前向安全性似乎在告訴你,如果當前時間點的密鑰泄露了,之“前”走過的所有密鑰節點都還是安全的。這樣一來,前向安全性就是說歷史密鑰是安全的,而后向安全性自然就是未來密鑰是安全的嘛(版本一)
誠然,有的讀者可能是這么理解的:前向安全性的英文是Forward Security,而后向是Backward;而直覺上當你看到「Backward」一詞時,腦海里同樣會浮現出一根時間軸,這個詞似乎在告訴你,如果當前時間點的密鑰泄露了,那么往“回”(Backward)走的所有密鑰節點都還是安全的。這樣一來,后向安全性就是說歷史密鑰仍是安全的,而前向安全性自然就是未來密鑰仍是安全的嘛(即版本二)
說實話,我自己的直覺理解是版本二,但實際上,目前學術界公認的正確定義其實是版本一。
如何理解?
可能和我一樣認為版本二是正確的讀者不是很能理解版本一中的 前(Forward)與后(Backward) 究竟指的是何處的 前與后,明明讓Backward對應“曾經”,Forward對應“未來”就很通順嘛。其實這種對應關系本身在語義邏輯上并沒有問題,只是在密碼學家看來,二者并非這么去理解。
在版本二的錯誤定義中,Forward 與 Backward 被理解為在當前密鑰泄露之后,哪個時刻是否還是安全的?即 前與后 修飾的其實是 結果時刻 相對于 密鑰泄露的發生時刻,如下圖所示。
而在版本一的正確的定義中,Forward 與 Backward 被理解為哪個時刻的密鑰被泄露了,目前是否還是安全的?即 前與后 修飾的其實是 密鑰泄露的發生時刻 相對于 結果時刻,如下圖所示。
因此,在兩種版本的理解中,Forward與Backward的方向是相反的(如圖中的虛線箭頭),而至于為什么版本一是正確的,而版本二并不太被接受呢?
個人認為,這是因為正確定義刻畫的是當系統從安全的正常狀態,逐漸轉移到不安全的不正常狀態(密鑰被泄露了)的過程中,安全性的變化,即強調出了密鑰泄露這一時刻的位置。錯誤定義雖然看起來更符合人們的思考邏輯,即面對著當前不正常的系統狀態,那些正常的系統狀態中安全性是如何的。然而正確定義更能描述清楚系統安全性的演化過程,這比單純符合人們第一印象來的要更為「學術化」一些。
總結一下吧
前后向安全性是很多密碼方案都會考慮的一個安全目標,例如密鑰協商、可搜索加密等等。本文對這一概念重新進行了梳理,也討論了兩種版本定義該如何去理解。最后,如果大家懶得看這么多,可以按照“前”是以“前”還安全,“后”是以“后”還安全,這樣去記就好。
啰嗦了這些,其實本質上只是文字游戲罷了,而且兩個版本的定義并不存在絕對的正確與錯誤,有些專業論文也都在混用。讀者還是要把握前后向安全性的精髓,以及這兩個定義究竟有什么意義,這才是最為重要的。
感謝你的閱讀,最后同樣以一句歌詞作為結束。
“十年之前你不認識我,我不屬于你,我們還是一樣” —— 林夕《十年》
參考
[1] https://www.di.ens.fr/users/phan/secuproofs/yao82.pdf
[2] https://crypto.stackexchange.com/questions/41140/is-every-pseudorandom-generator-a-one-way-function
[3] https://en.wikipedia.org/wiki/Forward_secrecy
[4] https://users.ece.cmu.edu/~adrian/projects/sec/node6.html
其他參考閱讀
https://crypto.stackexchange.com/questions/39761/definitions-of-secrecy
https://www.zhihu.com/question/45203206
https://www.quora.com/What-is-exactly-backward-secrecy-property-in-cryptography-attribute-based-encryption
https://en.wikipedia.org/wiki/Forward_secrecy
https://sunhuachuang.gitbooks.io/sun-note/content/cryptography/forward_backward_secrecy.html
https://users.ece.cmu.edu/~adrian/projects/sec/node6.html
總結
以上是生活随笔為你收集整理的密码学之前后向安全性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享一个边看视频就能边练口语的学习网站,
- 下一篇: mysql distinct count