如何存储iv,salt和密文?

时间:2015-10-22 14:11:11

标签: java encryption hex byte

on how to achieve password based encryption开始,我需要保存salt,IV和密文以便以后解密。

从此iv and salt can be stored along with cipher text

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

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

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

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

输出清楚地表明盐,iv结束的地方很糟糕

lIvyAA/PZg4=fE4gTZUCPTrKQpUKo+Z1SA==4/gAdiOqyPOAzXR69i0wlC7YFn9/KOGitZqpOW2y3ms=

以十六进制格式存储会有数据丢失的影响吗?

IV的长度是否恒定?在我的情况下,它总是32个字符(十六进制) 或者我甚至需要存储IV的长度?因为盐长度最初固定为8位(16个十六进制字符)

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

2 个答案:

答案 0 :(得分:1)

Base64 3字节的块编码为 4 base64 chars 。如果需要编码的字节数a = 3,则最后一个块的乘数用一个或两个=填充,以指示该块不满3个字节。

由于盐和静脉注射都不需要保密,因此确实无法检测到它们开始或停止的位置。 base64填充字符=是一个问题 - 但你应该有办法分离三个编码的字符串。你可以,例如只需使用:分隔部分。

IV的大小与加密算法的块大小相同。在这种情况下,您使用 AES ,其块大小为 128位 16字节。如果十六进制编码,这将提供 32字节,如果base64编码,则提供 24字节。 Salt实际上没有固定的长度,这取决于你的实施。

答案 1 :(得分:1)

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

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

了解并接受这一点很重要,否则你会想到一个试图混淆不重要事情的轴。默默无闻是没有安全感的。

然而,重要的是要注意,盐应该在加密强的伪随机数生成器中生成。应为每个正在加密的新纯文本生成新的salt。同样,应该为每个新的密文随机生成IV。

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

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