我希望这是我的问题的正确位置,因为这肯定不止一种方法。
我有一个压缩和加密的文件格式(xml)。现在我想将一些基本的未加密元数据附加到我的文件中,以便于访问某些参数。
是否有正确的方式来做我想做的事情,否则要记住哪些最佳做法?
我现在考虑的方法是在C#中使用Bouncy Castle来加密我的实际数据,同时将我的标记数据添加到文件的前面。
e.g。
<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
答案 0 :(得分:2)
像您一样使用XML组合非加密和加密数据确实是一种方法。在您的情况下,有一些缺点可能相关或不相关:
压缩相当有限。如果加密数据很大,您应该考虑直接以二进制格式存储它。此外,CDATA可能是一种折衷方案,尽管您在CDATA中放置的字符范围也是有限的。
如果加密数据很大,解析XML可能会很慢。此外,它通常需要将整个文档保留在内存中,这可能不是您想要的。同样,直接以二进制格式存储加密数据是一种解决方案。 CDATA在这里没有帮助。
XML的好处是人类可以读取。虽然与元数据相关,但无论如何大多数数据都被加密似乎很奇怪。
您可以考虑的其他替代方案:
并排两个文件。一个将包含二进制数据,另一个(名称相同但扩展名不同)将包含元数据(例如XML格式) 。困难在于您必须处理诸如存在二进制数据文件但不存在相应的元数据文件或相反的情况,以及复制/移动数据(NTFS has transactions,但您必须使用Interop,除非最新版本的.NET Framework添加了对Transactional NTFS的支持。
元数据和加密数据以二进制格式存储在单个文件中。 The answer by scottfavre显示了一种可能性。我同意他的解释,但宁愿压缩元数据有两个原因:(1)节省空间和(2)防止最终用户手动修改元数据,这将使标题无效。
我不推荐单二进制文件方法,因为它使格式难以使用;如果您发现(在进行了足够的基准测试和分析之后)有一个重要的性能优势,那么有效的情况就是这样。
存储在备用数据流中的元数据(仅可在NTFS中使用,因此请注意FAT格式的闪存驱动器)。这里的好处是您不必处理存储在头文件中的偏移量:NTFS会为您执行此操作。但这不是我建议的方法,除非您绝对需要将数据与文件保持在一起,并且您知道该文件将始终存储在NTFS磁盘上(并使用支持ADS的应用程序进行传输)。
答案 1 :(得分:2)
这里的一个挑战是将纯文本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的长度,准确读出那么多字节,输入流应该在正确的位置开始解密和解压缩文件的其余部分。 / p>
当然,既然您已经获得了二进制标头,那么您可以考虑在标头本身中放置元数据,而不是将其放在XML中。