【问题标题】:Proper handling of own file format in Java在 Java 中正确处理自己的文件格式
【发布时间】:2015-08-04 15:52:05
【问题描述】:

我必须为 Android 应用程序创建自定义文件格式(基于字节)。 这些格式的主要目的是保存一个 AES 加密文件(字节数据)和一些解密所需的元数据(例如 IV、Salt 和几个应用程序设置)。

我有几个关于如何设计和实现这个的问题:

  1. 文件中的必填字段是什么?

目前的想法是从 4 字节的幻数开始,然后是格式的版本号。紧随其后的是 IV 和 Salt。然后我将包含原始(未加密)数据的前 4kb 的校验和,因此我可以快速解密前 4kb 并检查提供的密钥是否正确。然后是整个原始(未加密)数据的校验和,这样我也可以检查整个文件。 这就是标题。 (我需要((未)加密的)数据的长度吗?数据的偏移量?整个(标题+正文)文件的校验和?)

对于正文(现在已加密),我想添加原始文件名和扩展名(应该使用多少字节?)。 然后是原始文件。

  1. 在 Java 中读取/写入此类基于字节的文件的最佳方法是什么?

我发现的两个主要方法是 ByteArrayOutputStreams 和 RandomAccessFiles。对于第一个选项,我缺少 seek 选项,例如如何在特定位置(即校验和)写入?第二个似乎运作良好,但也许有更好的解决方案可用。

【问题讨论】:

  • consensus 是您应该使用 encrypt-then-MAC 而不是 MAC-then-encrypt(这就是您的提议)。这意味着您通过强大的 MAC 算法(例如 HMAC-SHA256)运行生成的 AES 密文。问题仍然是如何派生用于 MAC 算法的密钥。

标签: java android encryption checksum file-format


【解决方案1】:

对于我的 H2 数据库,我实现了一个文件系统抽象,具有多个文件系统实现,包括 encrypted file。还有许多其他文件系统实现,例如缓存包装器等。

我会使用XTS (XEX-based tweaked-codebook mode with ciphertext stealing),这就是我实现的。它允许随机访问读取和写入,并且不会比纯 AES 慢多少。

您建议的标题对我来说听起来不错:幻数,然后是格式的版本号。我结合了幻数和版本号(不同的版本会产生不同的幻数)。使用 XTS,不需要 IV。 Salt,我会使用很多,例如 8 个字节。我还存储了散列迭代来散列密码,为此我使用了PBKDF2。我认为使用 PBKDF2 之类的东西很重要。

我将标头设置为 4096 字节长,以匹配常规文件系统的块大小。如果您使用固定块大小进行读写,这应该会提高性能。我没有使用任何校验和,因为我的底层(未加密)文件有一个校验和。我认为这已经足够了,而且可能比存储未加密数据的未加密校验和更安全,但我不确定。

对于 API,使用 ByteBufferbyte[] 都可以。有了ByteBuffer,支持内存映射文件就更简单了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多