4

I've found recently in the I2P sources (Java) the following fragment:

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;
}

As I understand, the first 256 bits of buf[] are copied directly to the session key, and no SHA256 digest is ever run on it. I'm not cryptography specialist (neither java), could anyone explain me, isn't it security hole here? I mean, in the standard Diffie-Hellman wiki page the SHA hash is also run over the key. If it really is, could you also give an example how it can be exploit?

4

2 回答 2

5

从攻击者可以利用密钥交换的意义上说,没有“泄漏”,但肯定会损失熵。因为密钥的大小似乎是 32 字节,所以这可能不是灾难性的,但我个人很难接受这种实现。

Diffie-Hellman 协议在RFC 2631中明确规定

必须保留前导零,以便 ZZ 占用与 p 一样多的八位字节。

在协议的实现中不存在前导零的这种保留。

最后,因为设计者决定不填充,所​​以有重叠的值:70,例如会被认为是相同的值,而它们显然不是7000700000

此外,将返回有符号BigInteger.toByteArray()的二补码编码。这意味着它通常会用有价值的字节填充,即使该值已经与八位字节中的 p 具有相同的大小。所以密钥的第一个字节很有可能是. 即使不是,第一个字节也受模数限制,因此第一个字节的值永远不会高于编码 p 的第一个字节。0000

更新:我在 crypto.stackexchange.com 上询问是否可以将其余关键字节视为由随机 Oracle(一种似乎向外界生成随机字节的确定性函数)生成的,幸运的是他们似乎可以。这意味着 AES 密钥中有足够的熵可以安全地抵御对 AES 分组密码的(暴力)攻击。

正如所解释的,由于密钥大小很大,很可能即使是所有这些缺陷的总和也不能被轻易利用。但绝对可以肯定的是,密钥不会像预期的那样携带 256 位的熵。这足以让密码分析师宣布这个实现被破坏了。当然,使用较小的密钥大小会更糟。

注意:所有值均以十六进制表示。

于 2013-07-24T23:31:01.970 回答
4

正如 owlstead 所解释的,这不是一个安全漏洞。但这一个自 I2P 开始以来就存在的错误,我们将对其进行修复。不幸的是,修复此问题所需的更改与我们现有的传输不向后兼容,因此这将被合并到我们传输的下一个版本中。

有兴趣的人可以在这里关注这个错误的进展。

于 2014-02-17T00:23:31.010 回答