将未加密的标签数据附加到加密文件

本文关键字:加密 文件 标签 数据 | 更新日期: 2023-09-27 18:33:52

我希望这是我的问题的正确地方,因为肯定有不止一种方法可以做到这一点。

我有一个压缩和加密的文件格式(xml(。现在的事情是,我想将一些基本的未加密元数据附加到我的文件中,以便于访问某些参数。

有没有一种正确的方法来做我想做的事情,否则需要记住哪些最佳实践?

我现在考虑的方法是使用 C# 中的 Bouncy Castle 来加密我的实际数据,同时将我的标记数据放在文件的前面。

例如

<metadata>
    //tag information about the file
</metadata>
<secretdata>
    //Grandma's secret recipe
</secretdata>

仅加密机密数据

<metadata>
    //tag information about the file
</metadata>
^&RF&^Tb87tyfg76rfvhjb8
hnjikhuhik*&GHd65rh87yn
NNCV&^FVU^R75rft78b875t

将未加密的标签数据附加到加密文件

这里的一个挑战是将纯文本 XML 从文件的前面移开,同时将输入流保留在加密和压缩数据的开头。由于 C# 中的 XML 读取库在构建时没有考虑到这种用法,因此它们可能表现不佳(例如 - 读取器读取的字节数可能超过其需要的字节数,使基础流超过加密数据的开头(。

处理它的一种可能方法是以提供 XML 元数据长度的已知格式预置标头。因此,该文件将如下所示:

Header (5 bytes):
    Version* (1 byte, unsigned int)         = 1
    Metadata Length** (4 bytes, unsigned int) = N
Metadata (N bytes):
    well formed XML
Encrypted Data (rest of file)

(* -在定义文件格式时包括版本控制总是一个好主意(

(** - 如果要超出元数据长度的 32 位 uint 范围,则应考虑另一种解决方案。

然后,您可以直接读取 5 字节标头,解析出 XML 的长度,准确地读出那么多字节,输入流应该在正确的位置开始解密和解压缩文件的其余部分。

当然,现在您已经有了二进制标头,您可以考虑只将元数据放在标头本身中,而不是将其放在 XML 中。

像您一样使用 XML 组合未加密和加密的数据确实是一种方法。有一些缺点可能与您的情况相关,也可能无关:

  • 压缩相当有限。如果加密数据很大,则应考虑直接以二进制格式存储。此外,CDATA 可能是一个折衷方案,尽管您可以在 CDATA 中输入的字符范围也是有限的。

  • 如果加密数据很大,则 XML 的分析可能会很慢。此外,它通常需要将整个文档保存在内存中,这可能不是您想要的。同样,直接以二进制格式存储加密数据是一种解决方案。CDATA 在这里无济于事。

  • XML 的好处是人类可以读取。虽然与元数据相关,但无论如何,当大多数数据都加密时,这似乎很奇怪。

您可以考虑的其他替代方案:

  1. 两个文件并排。一个将包含二进制数据,另一个(名称相同但扩展名不同(将具有元数据(例如 XML 格式(。困难在于您必须处理诸如存在二进制数据文件但不存在相应的元数据文件或相反的情况,以及数据的复制/移动(NTFS 具有事务,但您必须使用互操作,除非最新版本的 .NET Framework 添加了对事务性 NTFS 的支持(。

  2. 元数据和加密数据以二进制格式存储在单个文件中。斯科特法夫尔的回答表明了一种可能性。我同意他的解释,但也宁愿压缩元数据,原因有两个:(1( 节省空间和 (2( 防止最终用户手动修改元数据,这将使标头无效。

    我不推荐单二进制文件方法,因为它使格式难以使用;如果您发现(在进行了足够的基准测试和分析之后(存在重要的性能优势,则有效的情况是。

  3. 存储在替代数据流中的元数据(只能在 NTFS 中使用,因此请注意 FAT 格式的闪存驱动器(。在这里,好处是你不必处理存储在标头中的偏移量:NTFS为你做这件事。但这不是我推荐的方法,除非您绝对需要将数据与文件一起保存,并且您知道文件将始终存储在 NTFS 磁盘上(并使用 ADS 感知应用程序传输(。