計(jì)時(shí)攻擊
Timing Attack ,時(shí)序攻擊,是一種側(cè)信道攻擊,攻擊者嘗試分析加密算法的時(shí)間執(zhí)行順序來推導(dǎo)出密碼。每個(gè)邏輯運(yùn)算都需要執(zhí)行時(shí)間,但是 根據(jù)不同的輸入值,精確測(cè)量執(zhí)行時(shí)間,根據(jù)執(zhí)行時(shí)間反推出密碼的一些區(qū)域 。
簡(jiǎn)單理解,就是破解密碼的人,通過不同的輸入策略組合嘗試去驗(yàn)證密碼,得到不同的執(zhí)行時(shí)間,從而反推出密碼的區(qū)域,降低破解密碼的難度。
下面可以使用Java簡(jiǎn)單描述一下。
我們看一下Java中的String equals方法(Java17)
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
//StringLatin1.equals
@IntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
以上方法中字符串比較一旦遇到不同的字符,那么就直接返回失敗。
那么看一下下面的3行代碼的執(zhí)行時(shí)間。
"adfg".equals("abcd");
"abfg".equals("abcd");
"abcg".equals("abcd");
以上的3行字符串比較方法執(zhí)行時(shí)間是不同的。
執(zhí)行時(shí)間: 第一行 < 第二行 < 第三行
假如現(xiàn)在我們要猜出另外一個(gè)字符串,那么如果我們用暴力窮舉猜測(cè)字符串,則 根據(jù)不同的字符串組合,得到的執(zhí)行時(shí)間是不一樣的,那么根據(jù)不同的執(zhí)行時(shí)間分析,就可以知道前面幾個(gè)字符串是否正確,從而縮小范圍 。
以上是一個(gè)計(jì)時(shí)攻擊的簡(jiǎn)單例子,實(shí)際密碼加密,公私鑰加密算法是比較復(fù)雜的,但是也要考慮計(jì)時(shí)攻擊的影響。
多年前斯坦福的教授們專門針對(duì)這些問題發(fā)表過相關(guān)的論文,下面這篇于2005年發(fā)表在《Computer networks》的期刊論證了遠(yuǎn)程網(wǎng)絡(luò)計(jì)時(shí)攻擊的可能性。
計(jì)時(shí)攻擊的防御
那么對(duì)于計(jì)時(shí)攻擊這種要如何防止呢, 大部分的做法是使單向加密,或者密碼驗(yàn)證的算法執(zhí)行時(shí)間不會(huì)隨著輸入值的不同而規(guī)律變化 。換句話說就是 不同的輸入值的執(zhí)行時(shí)間相同 ,或者 執(zhí)行時(shí)間隨機(jī)分布 , 無法規(guī)律判斷 。
2009年jdk6的一個(gè)升級(jí)中就有相關(guān)的優(yōu)化來防止計(jì)時(shí)攻擊。MessageDigest是java.security包里面的類,主要用于SHA或 MD5 等密碼上安全的報(bào)文摘要功能而設(shè)計(jì)。最終會(huì)用到其equals方法。而這個(gè)改動(dòng)就是針對(duì)equals方法。
其中關(guān)鍵的改動(dòng)就是判斷字符串相等時(shí),不再看到不相等的字符就返回false。而是 對(duì)比完所有的字符之后再返回結(jié)果 。這樣代碼的執(zhí)行時(shí)間就大致相同。
同時(shí)2021年jdk8的補(bǔ)丁也有相關(guān)的優(yōu)化,
乍一看上面的代碼已經(jīng)比較完美了。但是。。。。
密碼字符串的信息 還有長(zhǎng)度信息
還是有坑哈。。。。。
其實(shí)上述中的代碼還有一個(gè)問題,就是 不同長(zhǎng)度的字符串的執(zhí)行時(shí)間也不一樣 ,那么如果我搞一輪不同長(zhǎng)度字符串窮舉之后,可以 根據(jù)運(yùn)行計(jì)算時(shí)間的不同可以推出密碼的長(zhǎng)度 。再進(jìn)行破解相對(duì)容易一點(diǎn)。
再看如今Java17中的這個(gè)方法, 長(zhǎng)度不同時(shí)也不會(huì)立馬返回false ,而是照常執(zhí)行整個(gè)代碼,這樣就避免了根據(jù)執(zhí)行時(shí)間先得到密碼的長(zhǎng)度。
//MessageDigest
public static boolean isEqual(byte[] digesta, byte[] digestb) {
if (digesta == digestb) return true;
if (digesta == null || digestb == null) {
return false;
}
int lenA = digesta.length;
int lenB = digestb.length;
if (lenB == 0) {
return lenA == 0;
}
int result = 0;
result |= lenA - lenB;
// time-constant comparison
for (int i = 0; i < lenA; i++) {
// If i >= lenB, indexB is 0; otherwise, i.
int indexB = ((i - lenB) > >> 31) * i;
result |= digesta[i] ^ digestb[indexB];
}
return result == 0;
}
小結(jié)
以上就是計(jì)時(shí)攻擊的一些簡(jiǎn)單內(nèi)容,網(wǎng)絡(luò)安全中的冰山一角。再次致敬這些維護(hù)JDK源碼的大師們!
-
JAVA
+關(guān)注
關(guān)注
20文章
2988瀏覽量
109031 -
字符
+關(guān)注
關(guān)注
0文章
237瀏覽量
25567 -
代碼
+關(guān)注
關(guān)注
30文章
4896瀏覽量
70565 -
加密算法
+關(guān)注
關(guān)注
0文章
218瀏覽量
25822
發(fā)布評(píng)論請(qǐng)先 登錄
最新防攻擊教程
CC攻擊
網(wǎng)絡(luò)攻擊的相關(guān)資料分享
cc攻擊防御解決方法
對(duì)Rijndael的JAVA差分攻擊與防范
java中數(shù)組的三種定義方式_java中數(shù)組的定義及使用方法(推薦)
java學(xué)習(xí)——java中的反射學(xué)習(xí)筆記
如何預(yù)防區(qū)塊鏈中的日蝕攻擊和DDos攻擊

如何區(qū)分Java中print和println
Java中創(chuàng)建對(duì)象有哪些方式
在Java中的線程狀態(tài)轉(zhuǎn)換

評(píng)論