2013-07-24 60 views
4

我已經在I2P源(JAVA)下面的代碼片段最近發現:I2P會話密鑰生成疑似泄漏

private final SessionKey calculateSessionKey(BigInteger myPrivateValue, BigInteger publicPeerValue) { 
    SessionKey key = new SessionKey(); 
    BigInteger exchangedKey = publicPeerValue.modPow(myPrivateValue, CryptoConstants.elgp); 
    byte buf[] = exchangedKey.toByteArray(); 
    byte val[] = new byte[32]; 
    if (buf.length < val.length) { 
     System.arraycopy(buf, 0, val, 0, buf.length); 
        ... //irrelevant details 
    } else { // (buf.length >= val.length) 
     System.arraycopy(buf, 0, val, 0, val.length); 
        ... //irrelevant details 
    } 
    key.setData(val); 
    return key; 
} 

據我瞭解,中buf[]第256位被直接複製到會話密鑰,並且沒有運行SHA256摘要。我不是密碼學專家(不是java),任何人都可以解釋我,這不是安全漏洞嗎?我的意思是,在標準Diffie-Hellman wiki頁面中,SHA散列也在密鑰上運行。 如果確實如此,你還可以舉一個例子來說明它是如何被利用的嗎?

回答

5

從攻擊者可以進入密鑰交換的意義上說,沒有「泄漏」,但確實存在熵的喪失。因爲關鍵似乎是32字節大小,這可能不是災難性的,但是我個人會接受這個實現很麻煩。

迪菲 - 赫爾曼協議中明確規定在RFC 2631

前導零必須保留,以便ZZ佔據儘可能多的八位位組爲p。

在協議的實現中不存在前導零的保存。

最後,因爲設計者決定不墊,所以存在值的重疊:70,7000700000將被認爲是相同的值,但它們顯然不是。

此外,BigInteger.toByteArray()將返回的雙補碼編碼值。這意味着即使值已經具有與八位字節中的p相同的大小,它通常仍被填充爲00值字節。所以密鑰的第一個字節是00真的很有可能。即使不是,第一個字節也會受到模數限制,所以第一個字節的值不會高於編碼p的第一個字節。

更新:我已經asked on crypto.stackexchange.com,看是否密鑰字節的其餘部分可以被認爲是由隨機Oracle和幸運they seem to do(這似乎產生隨機字節向外界確定性函數)的產生。這意味着AES密鑰中存在足夠的熵以抵禦AES分組密碼上的(暴力)攻擊。如上所述,由於密鑰的大小很大,因此即使所有這些缺陷的總和也很難被輕易利用。但絕對肯定的是,密鑰不會像預期的那樣攜帶256位的熵。這對於加密分析人員宣佈此實現中斷已足夠。當然,使用更小的密鑰大小會更糟糕。

注意:所有值都是十六進制。

3

正如貓頭鷹所解釋的,這不是一個安全漏洞。但它自I2P開始以來一直存在的錯誤,我們將解決。不幸的是,修正這個問題所需的修改與我們現有的傳輸不兼容,所以這些將被整合到我們傳輸的下一個版本中。

有興趣的人可以關注此bug的進展here