从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进行密码)
答案 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,我也会包括算法名称和迭代计数,而不是依赖于默认值。