将 sha2/sha3 截断为 16 个字节是否比使用本身给出 16 个字节开头的 crc32 更糟糕?

Is truncating sha2/sha3 to 16 bytes worse than using crc32 which itself gives 16 bytes to begin with?

我在 CBC 模式下使用 AES128,我需要一个 16 字节的密钥,所以我想知道如果使用 sha2 或 sha3 然后将其截断为 16 个字节(从左边取前 16 个字节)会使 sha2/sha3 比 crc32 弱,开箱即用,它给我 16 个字节。

加密安全哈希的每一位实际上都是随机的(即独立于所有其他位)。 non-cryptographic 哈希不是这样。 属性 对于安全密钥至关重要。您应该始终使用加密散列来派生密钥。

截断较长的安全散列是创建较短长度的安全散列的一种完全可以接受的方法。您还可以 select 位的任何子集,而不仅仅是最重要或最不重要的位。如果这不是真的,那么原始哈希本身就不安全,因为它会在输出中暗示一些 non-randomness。

SHA-2 和 SHA-3 打算成为加密安全的哈希值(在这一点上,我们相信它们是)。 CRC 甚至不打算加密安全。

如果输入密钥 material 本身不是随机的,那么像 SHA 系列这样的快速散列可能会受到暴力破解。如果是这样,那么您需要使用密钥拉伸和散列,例如使用 PBKDF2。

但是你永远不应该为这些使用 CRC。它不是一个安全的散列。

有关更多讨论,请参阅 Should I use the first or last bits from a SHA-256 hash?“SHA-256”与“SHA-512 的任何 256 位”,哪个更安全?

I am using AES128 in CBC mode, and I need a 16-byte key, so I was wondering if using sha2 or sha3 and then truncating it to 16 bytes (take first 16 bytes from the left) would make sha2/sha3 weaker than crc32 which gives me 16 bytes out of the box.

问题不清楚 CRC 或 SHAx 的输入是如何生成的。 OP清除了更多。因此,我在以下部分提供了答案;

I mean regardless of the input (say the input was even abcd ), would truncating sha2/3 to 16 bytes be more secure than using crc32.

首先,忘记CRC,它不是密码哈希函数,忘记它。

当输入space较小时,哈希函数有pre-image攻击的特例。攻击者可以尝试所有可能的组合来生成密钥。您可以在 Cryptography.SE Q/A

中阅读更多详细信息

忘了小输入 space!,像 BitCoin Miner or SuperComputer like Summit 这样的实体可以很容易地达到 2^64。这只是说 8 字节。

应该生成一个像 dicewire or Bip-39. This will provide you easy to remember and strong passwords. See also XKCD

这样的强密码

一旦你生成了一个好的密码,你就可以把它传给那个可怜人的 KDF1, to better use HKDF. Since your input material is good you can skip the expand part of the HKDF. You can also use the Password-based Key derivation functions like Scrypt, PBKDF2, and Argon2。在这种情况下,选择 Argon2,因为它是 2015 年 7 月密码哈希竞赛的获胜者。

I was just trying to encrypt data like sounds for a game with AES 128, and was just wondering if using only 16 bytes of the hashed password-like key with sha2/3 was a more secure solution than using a whole crc32 output instead. I've never worked with any of the other methods you mentioned...

为了正确使用 CBC 模式,您也需要一个随机数。您也可以使用具有不同 info/nonce 的 HKDF 或 PBKDF2、Argon2 等来导出随机数。这很常见。

注意关于 CBC 的那些;

  • nonce在同一个key下必须是唯一的,即(Key,IV)对must be used once
  • CBC IV 必须是 unpredictable,但是,据我所知,这不是你的情况
  • CBC 在 server-side 上容易受到 padding oracle 攻击。这在你的情况下也是不可能的。
  • CBC模式只能提供CPA安全,没有完整性和认证。要提供完整性和身份验证,请使用具有不同密钥的 HMAC,或使用组合模式。
  • 使用 Authenticated Encryption With Associated Data mode of encryptions like AES-GCM and ChaCha20-Poly1305. Correctly using the GCM may be hard,最好使用 ChaCha20-poly1305 或 xChaCha20-poly1305 以获得更好的随机数生成。