相等有時候也不安全!你知道嗎?
哈嘍,大家好,我是指北君。
最近世界杯看了幾場球賽,克羅地亞淘汰巴西, 摩洛哥淘汰葡萄牙。兩場都非常精彩,克羅地亞的堅韌令人佩服,絕境逆襲??傊@一屆世界杯絕對會影響以后足球的戰(zhàn)術打法。
言歸正傳哈,最近依然在搬磚哈,看到了關于計時攻擊的內(nèi)容,而這個又和我們常用的equals方法關系密切。然后就迫不及待的去扒一扒了。
? 計時攻擊
Timing Attack ,時序攻擊,是一種側(cè)信道攻擊,攻擊者嘗試分析加密算法的時間執(zhí)行順序來推導出密碼。每個邏輯運算都需要執(zhí)行時間,但是根據(jù)不同的輸入值,精確測量執(zhí)行時間,根據(jù)執(zhí)行時間反推出密碼的一些區(qū)域。
簡單理解,就是破解密碼的人,通過不同的輸入策略組合嘗試去驗證密碼,得到不同的執(zhí)行時間,從而反推出密碼的區(qū)域,降低破解密碼的難度。
下面可以使用Java簡單描述一下。
我們看一下Java中的String equals方法(Java17)
以上方法中字符串比較一旦遇到不同的字符,那么就直接返回失敗。
那么看一下下面的3行代碼的執(zhí)行時間。
以上的3行字符串比較方法執(zhí)行時間是不同的。
執(zhí)行時間: 第一行 < 第二行 < 第三行
假如現(xiàn)在我們要猜出另外一個字符串,那么如果我們用暴力窮舉猜測字符串,則根據(jù)不同的字符串組合,得到的執(zhí)行時間是不一樣的,那么根據(jù)不同的執(zhí)行時間分析,就可以知道前面幾個字符串是否正確,從而縮小范圍。
以上是一個計時攻擊的簡單例子,實際密碼加密,公私鑰加密算法是比較復雜的,但是也要考慮計時攻擊的影響。
多年前斯坦福的教授們專門針對這些問題發(fā)表過相關的論文,下面這篇于2005年發(fā)表在《Computer networks》的期刊論證了遠程網(wǎng)絡計時攻擊的可能性。
? 計時攻擊的防御
那么對于計時攻擊這種要如何防止呢,大部分的做法是使單向加密,或者密碼驗證的算法執(zhí)行時間不會隨著輸入值的不同而規(guī)律變化。換句話說就是不同的輸入值的執(zhí)行時間相同,或者執(zhí)行時間隨機分布,無法規(guī)律判斷。
2009年jdk6的一個升級中就有相關的優(yōu)化來防止計時攻擊。MessageDigest是java.security包里面的類,主要用于SHA或 MD5 等密碼上安全的報文摘要功能而設計。最終會用到其equals方法。而這個改動就是針對equals方法。
其中關鍵的改動就是判斷字符串相等時,不再看到不相等的字符就返回false。而是對比完所有的字符之后再返回結果。這樣代碼的執(zhí)行時間就大致相同。
同時2021年jdk8的補丁也有相關的優(yōu)化,
乍一看上面的代碼已經(jīng)比較完美了。但是。。。。
密碼字符串的信息 還有長度信息
還是有坑哈。。。。。
其實上述中的代碼還有一個問題,就是不同長度的字符串的執(zhí)行時間也不一樣,那么如果我搞一輪不同長度字符串窮舉之后,可以根據(jù)運行計算時間的不同可以推出密碼的長度。再進行破解相對容易一點。
再看如今Java17中的這個方法,長度不同時也不會立馬返回false,而是照常執(zhí)行整個代碼,這樣就避免了根據(jù)執(zhí)行時間先得到密碼的長度。
?小結
以上就是計時攻擊的一些簡單內(nèi)容,網(wǎng)絡安全中的冰山一角。再次致敬這些維護JDK源碼的大師們!
不斷防范,不斷升級才有了我們越來越安全的代碼。
jdk changeset:
- http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/562da0baf70b
- http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/54441ec952f7
- http://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf