如何存储iv、salt和密文?

for*_*t17 6 java encryption hex byte

如何实现基于密码的加密来看,很明显我需要保存盐、IV 和密文以便稍后解密。

由此iv 和 salt 可以与密文一起存储

我以这种格式存储十六进制值

DatatypeConverter.printHexBinary(salt) + DatatypeConverter.printHexBinary(iv) + DatatypeConverter.printHexBinary(ciphertext);

我需要以二进制格式存储值吗?

DatatypeConverter.printBase64Binary(salt) + DatatypeConverter.printBase64Binary(iv) + DatatypeConverter.printBase64Binary(ciphertext));

输出清楚地表明盐、静脉注射结束的位置,这太糟糕了

lIvyAA/PZg4=fE4gTZUCPTrKQpUKo+Z1SA==4/gAdiOqyPOAzXR69i0wlC7YFn9/KOGitZqpOW2y3ms=
Run Code Online (Sandbox Code Playgroud)

以十六进制格式存储是否会导致数据丢失?

IV 的长度是恒定的吗?就我而言,它始终是 32 个字符(十六进制),或者我什至还需要存储 IV 的长度?因为盐长度最初固定为 8 位(16 个十六进制字符)

(我使用 PBKDF2WithHmacSHA1 算法进行密钥生成,使用 AES/CBC/PKCS5Padding 进行密码)

Fru*_*Guy 6

我认为值得再次强调上面顺便提到的已接受的答案。

也就是说,尝试隐藏盐或 IV 是不必要和没有根据的。密码学的安全性完全取决于密钥的保密性,并且仅取决于密钥的保密性。IV 和盐可以与密文一起以明文形式分发,只要秘密密钥仍然是秘密,密文就保持安全。

理解并接受这一点很重要,否则你会试图混淆不重要的事情,从而让自己陷入困境。默默无闻中没有安全感。

然而,值得注意的是,盐应该在密码学上强的伪随机数生成器中生成。应该为每个正在加密的新纯文本生成一个新的盐。同样,IV 应为每个新密文随机生成。

这些参数需要是独立且不可预测的,但不需要保密。

因此,您可以将它们存储在单独的字段中或将它们分隔在单个字段中,或者对三个字段中的前两个字段使用固定长度。不过,为了获得最大的灵活性和面向未来,我建议使用分隔字段,并包含处理数据所需的所有参数。如果您使用 PBE,我也会包含算法名称和迭代计数,而不是依赖默认值。


Ebb*_*sen 2

Base64将3 个字节的块编码为4 个 Base64 字符。如果需要编码的字节数不是 3 的倍数,则最后一个块将用 1 或 2 填充=,以表明该块不是完整的 3 个字节。

由于盐和 IV 都不需要保密,因此能够检测到它们的开始或停止位置确实没有任何问题。Base64 填充字符=不是问题 - 但您应该有一种方法来分隔三个编码字符串。例如,您可以简单地用 分隔各个部分:

IV 的大小与加密算法的块大小相同。在本例中,您使用块大小为128 位(即16 字节)的AES。如果采用十六进制编码,则为 32 个字节;如果采用 Base64 编码,则为 24 个字节。盐实际上没有固定的长度,并且取决于您的实现。