我正在使用Shamir的秘密共享方案创建一个java应用来加密文件,因为我不能一次加密整个文件,我想分段加密 - 例如,一个int(四个字节)一次。基本上,将文件作为字节流读取,并一次加密n个字节。
问题是,加密的片段可以比输入更大或更小。所以我最终得到一个四字节值加密为五个字节等。这意味着我不能简单地连接所有加密的部分来创建加密文件 - 我需要一些方法来划分碎片。什么是一个好方法呢?
答案 0 :(得分:3)
在不了解密文域并且假设每个字节值都可以在密文中的情况下,我建议使用前置策略。
您应该在每个加密的int之前添加一个字节,以显示下一个部分密文的长度。对于长度为4和5的部分密文,您将获得六分之一到五分之一的密文扩展。这也适用于长度为255字节的部分密文。
如果需要长于255个字节的部分密文,则需要进行可变长度编码。 Apache Lucene定义了例如VInt。
这种编码的优点在于,如果底层流支持跳过,则可以轻松跳过长部分密文而不读取它们。使用分隔符是不可能的。
您仍然可以使用分隔符来执行此操作,但如果密文字节值分布均匀,则密文的平均值会略高一些。
以分隔符字节0x00为例。它分隔每个部分密文,但密文本身也可能包含0x00字节。现在你需要转义0x00密文字节,例如0xFF00,每个0xFF为0xFFFF。如果您现在遇到一个0x00字节,那么您可以确定它是一个分隔符,如果遇到0xFF00或0xFFFF,则将其转换为密文的0x00或0xFF。
正如你所看到的,转义一个字节的概率是2比256.这与之前的可变长度int大致相同,但没有跳过的便利。实现难度从构建可变长度的int变为正确的unescape密文字节。
答案 1 :(得分:1)
可能的解决方案:
加密后,数据大小是已知的。
以下列格式创建字节结构:
{长度使用整数} {加密数据} {长度-使用整数} {加密数据} ......
因此,当您开始读取要解密的数据时,首先读取长度,然后读取长度提到的字节数,依此类推。
答案 2 :(得分:1)
标准解决方案是按加密块的大小为加密块添加前缀。 如果要减小最终文件大小,可以使用一个字节来存储下一个加密块的大小,而不仅仅是每个int。例如:< 53>< 53字节加密>< 12>< 12字节加密> ..
如果您的块可能超过255个字节,那么您可以使用变量strcuture来存储大小(无符号):从0到127的一个字节,从128到32767的两个字节,依此类推。