i2p会话密钥生成怀疑泄漏

Ser*_*gei 4 security cryptography sha256

我最近在I2P源代码(Java)中发现了以下片段:

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;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,前256位buf[]被直接复制到会话密钥,并且没有运行SHA256摘要.我不是加密专家(也不是java),任何人都可以解释我,这不是安全漏洞吗?我的意思是,在标准的Diffie-Hellman维基页面中,SHA哈希也在密钥上运行.如果确实如此,您是否也可以举例说明如何利用它?

Maa*_*wes 5

在攻击者可以利用密钥交换的意义上没有"泄漏",但肯定会丢失熵.因为密钥大小似乎是32字节,这可能不是灾难性的,但我个人在接受这种实现时会遇到很多麻烦.

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

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

在协议的实现中不存在对前导零的保留.

最后,因为设计师决定不垫,有是值的重叠:70,7000并且700000将例如作为相同的值来理解,而他们显然不是.

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

更新:我已经在crypto.stackexchange.com询问是否可以认为其余的关键字节是由随机Oracle生成的(确定性函数似乎会向外界生成随机字节),幸运的是它们似乎这样做.这意味着AES密钥中剩余足够的熵可以抵御AES分组密码上的(强力)攻击.

如上所述,由于密钥尺寸较大,即使是所有这些缺陷的总和也很难被轻易利用.但绝对可以肯定的是,密钥不会像预期的那样携带256位熵.这对于加密分析师来说足以宣布这个实现被破坏了.当然,使用较小的密钥大小会更糟糕.

注意:所有十六进制值.