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

嵌入式Linux设备的高效存储远程文件完整性检查,linux,Linux,我有嵌入式Linux设备,内存和闪存有限。 由于RAM和闪存的限制,我需要从HTTP服务器下载二进制文件,并将其分成小块,然后将该块写入闪存。 问题是,在下载最后一个块之前,我无法确定文件的完整性。在最坏的情况下,在获取文件的最后一块后,我可能会发现该文件被篡改,或者它不像我预期的那样是“完整的”,但我已经分块下载并写入闪存。我可以在最后一块后将闪存下载区标记为有效,但是到那时我已经浪费了时间和短暂的生命 有没有办法向远程HTTP服务器发送请求,以验证文件的md5sum是否符合预期的md5sum

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

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

在客户端:

从服务器请求以m字节为单位的文件F的运行校验和cii=1,…,n列表。 创建一个哈希上下文C。 从服务器请求文件F。 对接收到的每m字节块bii=1,…,n重复: 更新哈希上下文:updateC,bi 计算当前摘要:di← digestC,bi 如果di≠ ci: 中止传输,报告错误,再试一次,不管怎样… 将区块bi保存到磁盘。 在服务器端:

如果客户机请求以m字节为单位的文件F的运行校验和cii=1,…,n的列表: 创建一个哈希上下文C。 对每m字节块bii=1,…,n of F重复: 更新哈希上下文:updateC,bi 计算当前摘要:di← digestC,bi 将di发送到客户端。 否则,如果客户端请求文件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...
解析标题以提取所需信息对您来说应该不难。当然,标题的格式需要根据您的具体需要进行调整

如果正在使用,则可能需要将校验和与每个块一起添加,而不是全部添加到开头,以便将服务器进程文件保存两次


请注意,以上所有内容只能帮助检测意外数据损坏。这是TCP已经试图使之不太可能的事情,所以我不确定过度悲观会给你带来多少好处。该方案无法防止中间人攻击。如果这是您关心的问题,那么您应该建立一个可信的TLS连接HTTPS,然后才传输文件。但是,如果有人闯入服务器,即使HTTPS也无法保护您。如果这也是应该处理的可能性,那么您可以使用OpenPGP对数据进行签名,并验证签名的完整性。当然,用于创建签名的私钥不能存储在服务器上。

您控制远程服务器吗?我的意思是,您可以请求/让它在发送文件之前为每MB发送一个中间校验和。如何获得整个文件的校验和?我无法控制远程服务器。”无法从HTTP服务器请求1 MB内存块的“实际校验和”而不是“预期校验和”;没有HTTP命令可以执行此操作。每MB的校验和只能确保该1MB的完整性。我需要检查整个文件的完整性。有人可以入侵HTTP服务器并更改二进制文件的一小部分。“每MB的校验和只能确保1 MB的完整性”——使用运行校验和可以做得更好:使用单个哈希上下文,将通常称为update的流函数全部提供给它,并在需要时向通常称为digest的当前校验和函数请求当前覆盖字节0。中间校验和是一个奖金,你得到的大部分是免费的,因为你正在计算总校验和无论如何。但是,如果您没有机会向服务器请求这些校验和,恐怕您的运气不好。如果您没有机会向服务器请求这些校验和,恐怕您的运气不好,因为我可能有权访问HTTP服务器。如果我有访问权限,那么如何使用HTTP/Etags实现呢?感谢Moritz提供详细的答案。让我消化一下,因为我是HTTP领域的新手!您说过,通过HTTP请求请求运行校验和的列表,如
我不太明白。这是标准HTTP请求格式吗?如何通过curlapi实现?HTTP服务器上需要更改哪些内容?只是内容或安装一些HTTP扩展?这是“标准HTTP”,在某种意义上说,它是标准允许的,但它不会自动为您工作。您需要在解析请求URL并生成和发送上述校验和的服务器上放置一个PHP脚本校验和或任何东西。撇开死角的情况不谈,我想你可以用不到100行的PHP来完成,但你还是必须这样做。