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