i2p会话密钥生成怀疑泄漏

时间:2013-07-24 18:09:52

标签: 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;
}

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

2 个答案:

答案 0 :(得分:5)

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

Diffie-Hellman协议明确指出RFC 2631

  

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

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

最后,因为设计师决定不填充,所​​以值重叠:707000700000例如被认为是相同的值,而他们显然不是。

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

更新:我asked on crypto.stackexchange.com看看其余的关键字节是否可以被认为是由一个随机Oracle(一个似乎为外界生成随机字节的确定性函数)生成的,幸运的是they seem to do。这意味着AES密钥中留有足够的熵以防止(强力)攻击AES分组密码。

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

注意:所有十六进制值。

答案 1 :(得分:4)

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

有兴趣的人可以关注这个错误的进展here