校验有两层,只看一层就一定会放过一个
一句话总结
哈希正确但签名损坏,与签名正确但哈希不一致,这两种情况的原因和应对方式完全不同;要区分二者,必须同时检查两个层级。
为什么需要这些知识
“已经通过验证”这句话比想象中更含糊。追问到底通过了什么,通常只能得到两个答案中的一个:核对过哈希,或者确认过签名。然而,二者保护的是不同对象。
文件哈希保护的是: 文件是否就是清单所声明的那个文件。它能发现文件在介质间转移时是否损坏,以及途中是否有人修改了文件。
签名保护的是: 清单是否由我们信任的人制作。它能发现清单本身是否遭到篡改。
本文的重点正是说明只检查其中一层会发生什么。
只检查文件哈希时。 假设有人修改了文件,为避免暴露,又把清单中的对应行改成新的哈希。所有文件哈希核对都会通过——因为核对依据正是修改后的清单。验证什么也发现不了。
只检查签名时。 清单和签名保持不变,只修改一个有效载荷文件。签名验证仍会通过——因为清单没有变化。被修改的文件随后会直接安装。
因此,两层都必须检查,而且检查顺序也已经确定。
它是如何运作的
接收方应按以下顺序执行。
1) 번들 전체 해시 매체에서 옮기다 깨졌는가. 틀리면 그 자리에서 끝.
2) 서명 검증 이 목록을 아는 사람이 만들었는가. 틀리면 파일은 볼 것도 없다.
3) 파일별 해시 목록이 말한 그 파일들이 맞는가.
为什么第 2 步要先于第 3 步? 如果先执行第 3 步,就会依据一份尚未确认真伪的清单进行核对。按照被修改的清单检查,所有内容自然都会匹配。仅仅调换顺序,就足以让验证失去作用。这是本模块最常出错的地方。
还有一点:如果公钥也放在包内,签名验证将无法保护任何东西。 控制这个包的人可以生成自己的密钥对,同时替换有效载荷、清单、签名和公钥。接收方会使用包内的公钥验证包内的签名,结果仍然通过。要让签名真正有意义,至少有一个信任根必须通过另一条路径到达。 公钥应与包分开传递;接收方应先与预先知道的指纹核对,然后再使用它。
在实际工作中会是什么样
两种失败的严重程度不同。 签名正确,但某个文件哈希不一致,很可能是传输过程中发生了损坏,重新接收通常就能解决。反过来,如果所有文件哈希都一致,签名却损坏,说明整份清单已经变化,不是重新接收即可了结的问题,汇报和升级路径也会不同。因此,导入记录中不应只写“验证失败”,而要注明在哪一个层级失败。
私钥的位置经常引发事故。 曾经有人将整个签名工作目录压缩后交付,结果把私钥也一并发了出去。私钥权限应设为 600,并且必须用 tar -tzf 亲眼确认包中到底包含什么。认为自己没有放进去,与清单中确实不存在,是两回事。
哈希文件和包会一起过时。 重新打包后,哈希就会改变。文档中记录的值、哈希文件和实际包必须始终一致,但重新打包的一瞬间,三者就会分离。如果不把打包、计算哈希和更新文档整合成同一个流程,它们必然出现不一致。
下一次实操要做什么
你将把同一个包解开成两份,并分别施加不同的篡改。第一份只修改二进制文件中的一个字节;第二份除了做同样修改,还会把清单中的对应行更新成新的哈希。随后,对两份包都执行签名验证和文件哈希核对,用数字确认各自在什么位置失败。亲眼看到两份结果恰好相反,就是这次实操的核心。