通过使用hashCode()的输出作为SHA256的输入,在生成一组对象的哈希时,任何安全强度的损失

use*_*604 0 java cryptography hashcode sha256 information-theory

我有一个对象集合,我希望从这个对象集合中生成一个哈希值(使用SHA256).

这些散列这些对象的过程是零知识证明系统的一部分,其中证明者生成证明,该证明稍后由验证者验证.这个证明实际上是哈希函数的输出.

这些对象都包含3或4个大的BigInteger值(大小为2048位).对象的数量是可变的,但它将在4到10之间.

我编写了以下方法,用于从可变数量的对象生成哈希值:

public byte[] buildHashFromHashcodes(final Object... listOfObjects) {

    for (Object obj : listOfObjects) {

        if (obj == null) {
            throw new Exception(
                "Input objects cannot be null");
        }

        _md.update(intToBytes(obj.hashCode()));
    }

    return _md.digest();
}

private byte[] intToBytes(final int intValue) {
    return new byte[] {(byte) (intValue >> 24),
            (byte) (intValue >> 16), (byte) (intValue >> 8),
            (byte) intValue };
}
Run Code Online (Sandbox Code Playgroud)

我的问题与在此代码中使用hashCode方法有关.具体来说,我试图确定hashCode方法的使用是否会削弱系统的安全性,因为它只生成一个32位数,因此只在每次迭代期间使用32位信息更新散列.因此,我不确定此过程中此信息的丢失是否真的会削弱系统.

这些对象的hashCode方法的实现使用大的BigInteger值来生成它们的哈希码,但是在返回之前该数字被截断为int.

我担心的部分原因是,某些对象的哈希码之间可能存在冲突.但话说回来,哈希在循环内部被多次更新,因此单个冲突不会是一个大问题.

让我们假设对象集合中有4个对象.在循环的第一次迭代中,将使用32位来更新散列,在第二次迭代中,将使用另外32位来更新散列,等等.

据我所知,在调用update方法之后执行散列算法.不是128位(4个对象)将存储在缓冲区中,然后使用这128位作为输入执行散列算法.

因此,我们可以说在最终更新之后哈希所处的状态总数将是(2 ^ 32)*(2 ^ 32)*(2 ^ 32)*(2 ^ 32)?(在实践中,这当然不会发生,因为它会在某些时候被截断).

我相信使用hashCode是一种安全的方法,因为在每次迭代期间都会调用update方法.

为了避免对象之间发生冲突的风险,另一种方法是使用每个对象的toString()方法,该方法返回一个包含每个对象的全部熵的String(大BigInteger数字的值包含在字符串).这意味着在循环的每次迭代期间使用更多信息更新散列,但我不确定是否有必要.

所以,我的问题是,在这段代码中使用hashCode方法会削弱系统的强度吗?

nne*_*neo 7

这是一个糟糕的主意.加密散列函数的目的是彻底混合输入数据,以便每个输入位影响每个输出位.

通过引入中间体hashCodes,您可以使每个输入BigInteger仅有机会影响一个32位hashCode.因此,单个32位hashCode中的冲突会导致最终散列完全冲突.

因此,要攻击您的方案,攻击者只需要找到与您的输入BigInteger对象之一具有相同hashCode的BigInteger.这完全不安全.