我们怎么知道展出的著名艺术品是真实的而不是伪造的?这显然不是一件容易的事,因为艺术品伪造行业估计每年产生约30亿美元的收入。艺术家经常在他们的原创作品上签名,但很难区分原始签名和复制品。
识别伪造品的一种方法是利用原子弹,或者更确切地说,在14年代原子弹试验之后在所有有机材料中发现的高碳-1960同位素比率的特征。如果用于结合油漆中颜料的有机物来自在此期间之前死亡的植物,则碳-14的比例将大大低于更现代油漆中的比例,从而使调查人员能够可靠地识别现代伪造品。
与艺术一样,我们经常更关心数据的真实性,而不是其他人是否能够查看它。例如,我们如何知道设备上运行的代码是真实的?我们并不总是关心隐藏代码 - 任何人都可以查看开源的u-boot引导加载程序代码。但是,在开始执行之前,我们的设备能够验证引导加载程序代码是否未经更改且真实,这一点至关重要。
本博客介绍了消息身份验证代码和数字签名,它们是验证数据的完整性(数据是否已更改?)和真实性(谁生成了数据?)的加密方法。但是,为什么不直接使用校验和或CRC来验证数据是否未被更改呢?正如我们将在下一节中看到的那样,不幸的是,它们无法抵御故意修改数据的对手。
为什么CRC不合适
验证数据是否已被更改的一种众所周知的方法是添加错误检测代码,例如循环冗余校验 (CRC)。例如,考虑由多项式 x+1 生成的 1 位 CRC。这相当于添加一个偶数奇偶校验位,如果数据中的 1 个数为奇数,则在数据后附加 1,否则附加 0。
如果我们10010111输入数据,我们可以看到数据中有一个奇数个 1,所以我们的奇偶校验位将是 1。那么,为什么这种有效的错误检测方案不适合确保完整性和真实性呢?
问题在于CRC相当于艺术家的签名。如果我们像CRC伪造者一样思考,设备怎么会被愚弄,接受更改后的数据不变?首先,让我们采用最简单的情况:假设数据及其CRC一起存储在未受保护的内存(例如闪存)中。攻击者需要做的就是用自己的数据覆盖原始数据,然后计算适当的CRC并将其附加到他们的数据中。当设备读取更改后的数据时,它将计算CRC并验证其是否与攻击者生成的CRC匹配,接受更改后的数据为原始数据!对于此攻击的真实示例,本演练详细解释了黑客如何通过操纵 Linux 内核中的 CRC 来控制 Docker 服务器。
规避 CRC:(左)原始代码和 CRC 通过验证,(中间)具有对抗性修改和原始 CRC 验证失败的代码,(右)具有对抗性修改和对抗性 CRC 通过验证的代码
为了使攻击者更难,该设备可以将CRC存储在一次性可编程(OTP)存储器中。不幸的是,这并不能消除问题。虽然CRC是检测通道噪声或不稳定单元良性错误的好方法,但它们不能防止主动恶意修改。
假设我们前面的示例数据用于启用或禁用不同的产品功能,具体取决于客户选择的许可证模型。如果高价值功能位于最左侧的位中,则能够更改我们的示例向量10010111将更左侧的位翻转为 1s 将启用这些功能,而无需为价格较高的许可模型付费。对于对手来说,这是微不足道的:
原始数据 | 修改后的数据 |
10010111 1 | 11110111 1 |
由于 1 位 CRC 在原始数据中为 1(表示数据中的奇数为 1),因此对手只需要确保修改后的数据也有奇数 1。通过将最左边的两个 0 翻转为 1,攻击者启用了两个额外的高价值功能,而无需修改安全存储在 OTP 中的 CRC 检查位。此策略也适用于实际应用中使用的较大 CRC。
重要的一点是,CRC仅提供良性错误保护,例如通信通道上的噪声或不稳定的SRAM单元。当攻击者主动尝试修改数据时,他们可以以一种不会改变从原始数据生成的CRC的方式进行修改。
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !