嵌入式Linux设备的存储高效远程文件完整性检查

时间:2014-10-20 20:35:15

标签: linux

我已经嵌入了具有有限RAM和Flash的Linux设备。 由于RAM和Flash有限,我需要以小块的形式从HTTP服务器下载二进制文件,然后将该块写入闪存。 问题是,在我下载最后一个块之前,我无法确定文件的完整性。在最坏的情况下,在获取文件的最后一块之后,我可能会发现文件被篡改或者它不是“整体”。正如预期的那样(我预计该文件的md5sum),但之后我已经下载了大块并写入了闪存。(我可以将闪存下载区域标记为最后一块后有效,但我已经浪费了时间和闪存生命到那个时候) 有没有办法向远程HTTP服务器发送请求,以根据预期的md5sum值验证文件的md5sum?

1 个答案:

答案 0 :(得分:0)

根据我对评论中讨论中的问题的理解,这是高级图片,假设您可以向服务器添加内容

在客户端:

  • 请求运行校验和的列表( c i i = 1,..., n 用于来自服务器的 m 字节块中的文件 F
  • 创建哈希上下文 C
  • 从服务器请求文件 F
  • 对每个 m 字节块重复( b i i = 1,...,n
    • 更新哈希上下文:更新( C b i
    • 计算当前摘要: d i ←摘要( C b <子>的 I
    • 如果 d i c i
      • 中止转移,报告错误,再试一次,等等......
    • 将块 b i 保存到磁盘。

在服务器端:

  • 如果客户端请求运行校验和列表( c i i = 1 ,<,> ,用于 m 个字节块中的文件 F
    • 创建哈希上下文 C
    • 对每个 m 字节块重复( b i i F 的i> = 1,...,n
      • 更新哈希上下文:更新( C b i
      • 计算当前摘要: d i ←摘要( C b <子>的 I
      • 向客户发送 d i
  • 如果客户请求文件 F
    • F 发送给客户。

此方案允许您通过正常的HTTP请求(例如file.dat)以1个Mib的文件http://example.com/checksums?algorithm=md5;file=file.dat;chunksize=1048576的块的形式请求运行校验和的列表(可能只是每行一个摘要的文本文件)。稍后可以像http://example.com/file.dat一样请求实际的文件数据。

或者 - 如果您认为大多数客户端需要校验和但不需要对算法或块大小进行细粒度控制 - 您可以添加其他HTTP头并使服务器的回复如下所示:

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 52428800
My-Checksum-Algorithm: md5
My-Checksum-Chunk-Size: 1048576
My-Checksum-Chunk: chunk=0, digest=c9a3a83280571697868f12e74e4ede4f
My-Checksum-Chunk: chunk=1, digest=d0c13dff943c5b67f411732304b6f46f
My-Checksum-Chunk: chunk=2, digest=34465c3e2e2eb2576d46253bea5cfc44
My-Checksum-Chunk: ...
My-Checksum-Total: f2bf55ff8b38dc667b91b6b988cdf940

Here goes the data...

解析标题以提取所需信息应该不难。当然,标题的格式需要根据您的特定需求进行调整。

如果您使用chunked transfer encoding,您可能希望将校验和与每个块一起添加,而不是在开头添加所有校验和,以便将服务器处理文件保存两次。

请注意,以上所有内容只能帮助检测意外数据损坏。 (这已经是TCP已经尝试做出的事情,因此我不确定你会因为过于悲观而获得多少。)这个方案不能做的是防止中间人攻击。如果这与您有关,则应建立受信任的TLS连接(HTTPS),然后才传输该文件。但是,如果有人闯入服务器,即使HTTPS也无法保护您。如果这也是应该处理的可能性,您可以使用OpenPGP对数据进行签名并验证签名的完整性。当然,用于创建签名的私钥不得存储在服务器上。