try ai
科普
编辑
分享
反馈
  • 侧信道攻击:聆听硬件的低语

侧信道攻击:聆听硬件的低语

SciencePedia玻尔百科
核心要点
  • 侧信道攻击利用的是时间变化或功耗等物理信息泄露,而非直接破解密码学算法。
  • 这些泄露的根本原因是数据依赖行为,即计算机的物理行为会根据其处理的秘密数据而改变。
  • 有效的缓解措施需要一种多层次的“恒定时间”方法,以确保程序的可见物理行为在任何秘密输入下都保持不变。
  • 侧信道分析的原理不仅限于密码学,还延伸到软件算法、操作系统、网络协议乃至量子计算系统。

引言

在数字安全领域,我们通常将攻击者想象成密码破译者,在完美的算法中寻找数学缺陷。但如果最大的漏洞不在于逻辑,而在于执行逻辑的物理机器呢?每一次计算,无论多么抽象,都有其物理足迹——它消耗时间、耗费电力、散发热量。这些物理表现并非总是统一的;它们常常根据正在处理的秘密数据而变化。侧信道攻击正是利用这些来自硬件的、微妙且无意的“低语”来窃取信息,从而完全绕过传统的密码学防御。

本文揭开数字抽象的表层,展示计算的物理现实及其带来的安全风险。它旨在弥合纯逻辑安全模型与真实世界硬件实现漏洞之间的关键知识鸿沟。通过理解信息如何泄露,我们可以学习如何构建更稳健的系统。首先,我们将探讨侧信道背后的核心“原理与机制”,审视时间、功耗以及缓存等微架构特性如何泄露秘密。随后,我们将在“应用与跨学科联系”部分拓宽视野,了解这些看似深奥的攻击如何在软件、操作系统乃至量子物理学等领域产生深远影响。

原理与机制

想象一下,你让朋友计算一个困难的乘法问题。你看不见他们正在计算的数字,但你站在旁边。你注意到他们花了很长时间,眉头紧锁,甚至可能用了一下计算器。通过这些“侧信道”——所花费的时间、可见的努力——你或许能推断出他们所乘数字的一些信息,比如数字非常大。

计算机,尽管在数字上尽善尽美,但仍是一台物理机器。当它进行计算时,它操纵电子,为电容器充电,并散发热量。与我们那个做数学题的朋友一样,它并非在无声、抽象的真空中完成工作。它通过各种侧信道向物理世界泄露信息。侧信道攻击的艺术不在于破解密码学的数学锁,而在于聆听硬件工作时发出的微妙低语。

低语之源:数据依赖行为

侧信道背后的基本原理是​​数据依赖行为​​(data-dependent behavior)。一台理想的、柏拉图式的纯逻辑计算机会以相同的方式执行指令,无论处理何种数据。而我们现实世界中为了速度和效率由硅和铜构成的计算机则没有那么纯粹。它们的物理行为——执行时长、功耗大小——常常取决于我们希望保密的那些数据。

时间侧信道

最直观的侧信道是时间。如果一个涉及秘密比特1的计算比涉及秘密比特0的相同计算耗时更长,那么一个拥有精确秒表的攻击者就能发现这个比特。这种时间差异可能源于系统中令人惊讶的不同层面。

在最高层面,算法本身可能就是罪魁祸首。考虑许多密码系统中用于计算 ae(modn)a^e \pmod nae(modn) 的经典“平方-乘”算法,其中 eee 是秘密指数。一个简单的实现可能会遍历 eee 的比特位,并执行如下操作:“总是对当前结果进行平方。如果 eee 的当前比特位是 1,则额外乘以 aaa。”。攻击者通过计时这个过程,会观察到处理“0”比特时的短操作(仅平方)和处理“1”比特时的长操作(平方加乘法)。秘密指数 eee 就这样在攻击者的秒表上被逐比特地读取出来。

泄露也可能更为微妙,深藏于处理器的微架构之中。在许多处理器上,某些“特殊”数字的计算比“正常”数字更困难。例如,IEEE 754 浮点数算术标准包含称为​​非规格化数​​(subnormals)的极小数字。由于其独特的表示方式,许多处理器必须脱离高度优化的快速路径,使用更慢、更复杂的硬件路径甚至微码辅助来处理它们。想象一个密码学例程,其中一个秘密值 sss 被一个攻击者控制的公开值 bbb 相除。攻击者可以选择 bbb,使得结果 s/bs/bs/b 当且仅当 sss 具有某个特定属性(例如,小于某个阈值)时成为非规格化数。通过测量除法时间,攻击者就能了解到关于秘密 sss 大小的一些信息。

单次这样的慢速操作可能只会给总时间增加几十纳秒。这能被检测到吗?当然可以。在一个场景中,某个操作执行了 100,000 次此类计算,当密钥具有特定值时,攻击者可以使其 20% 的结果变为非规格化数,那么每次操作的微小延迟就会累积成一个巨大且易于测量的信号。例如,在一颗 3.2 GHz 处理器上,每个非规格化数带来 176 个周期的延迟,最终可累积成 1.1 毫秒的总时间差——这在计算领域简直是永恒,比典型的测量噪声大数千倍。低语已变成呐喊。

功耗侧信道

另一个基本的侧信道是功耗。物理定律决定了改变比特的状态——从0翻转到1——需要能量。翻转的比特越多,消耗的能量就越多。攻击者在处理器附近放置一个灵敏的探头,便可以测量这些微小的功耗波动,从而创建功耗轨迹。通过对数千条这样的轨迹进行统计分析,一种称为​​差分功耗分析​​(Differential Power Analysis, DPA)的技术便可以揭示秘密。

功耗分析攻击的成功与否关键取决于​​信噪比​​(signal-to-noise ratio, SNR)。“信号”是由依赖于秘密数据的数据变化引起的功耗变化,而“噪声”则是芯片上所有其他无关活动产生的功耗。

不同的硬件平台为这种窃听创造了截然不同的环境。考虑在两种可编程芯片上实现一个密码学算法:一种是简单的复杂可编程逻辑器件(CPLD),另一种是复杂的现场可编程门阵列(FPGA)。CPLD 拥有少数几个大型逻辑块和一个简单、确定性的布线网络。当一个与秘密相关的操作发生时,它集中在一个区域内,产生一个干净、强烈的功耗信号。这就像在安静的图书馆里低语。相比之下,大型 FPGA 拥有大量分散的微小逻辑单元和复杂的布线结构。同样的操作被分散开来,其功耗特征被淹没在数千个其他无关开关事件的背景噪声中。这就像在嘈杂的摇滚音乐会上低语。由于信噪比更高,CPLD 本质上更容易受到功耗分析攻击。

内部迷宫:微架构信道

为了达到惊人的速度,现代处理器极为复杂,采用了流水线、缓存和推测执行等技术。这些性能增强特性创造了一个丰富而危险的侧信道环境,将处理器的内部状态变成了潜在的信息泄露源。

缓存:会背叛的存储器

CPU 缓存的核心是一个小而快的存储器,用于存放最近使用的数据,以避免访问主内存的漫长过程。缓存命中(在缓存中找到数据)速度快;缓存未命中(数据不在缓存中)速度慢。这个简单的事实是一些最强大侧信道攻击的基础。

著名的 AES(高级加密标准)算法可以使用称为 T-表的大型查找表来实现。这些表的索引由密钥派生。当算法运行时,它会根据秘密访问表项。攻击者可以计时加密过程。通过巧妙地操纵数据,他们可以确定哪些访问是快速的(缓存命中),哪些是缓慢的(缓存未命中)。经过多次运行,这就揭示了内存访问模式,进而揭示了密钥。为加速计算而设计的缓存,成了一名告密者。

预测器:机器中的幽灵

为了保持其深度流水线满载,现代 CPU 会尝试预测未来。例如,​​分支预测器​​(branch predictor)会在条件尚未计算出来之前就猜测 if-then-else 条件语句的结果。它的内部状态——一组计数器和历史寄存器——由已执行分支的历史所塑造。

现在,想象两个程序在同一个 CPU 核心上运行,由操作系统相互隔离。第一个程序是“发送方”,它有一个分支的方向取决于一个秘密比特。第二个程序是“接收方”,它有自己的分支。发送方运行,其依赖于秘密的分支将共享的分支预测器“训练”成特定状态。然后,操作系统切换到接收方。接收方的分支执行速度会因预测器被留下的状态而变快或变慢。通过计时自身的执行,接收方可以推断出预测器的状态,从而推断出发送方程序的秘密。这不再仅仅是听取低语;这是通过 CPU 自身的幽灵般预测机制进行通信。这类攻击的变种是像 Spectre 这样重大漏洞的基础。

缓解之术:恒定时间准则

如果问题是数据依赖行为,那么原则上的解决方案很简单:让行为​​与数据无关​​。这是​​恒定时间准则​​(constant-time discipline)的核心宗旨:确保程序的控制流和内存访问模式完全相同,无论其处理的秘密数据为何。在实践中,实现这一点是一项深刻的工程挑战,贯穿系统的每一层。

软件:重写规则

在软件层面,目标是编写不会泄露信息的代码。这通常意味着放弃标准的、为性能优化的编程模式。

为了修复易受攻击的平方-乘算法,我们不能简单地使用一个有时执行乘法的 if 语句。相反,我们必须在每一次迭代中都执行乘法。当秘密比特是“0”时,我们执行乘法,但只是简单地丢弃结果——这是一种​​伪操作​​(dummy operation)。关键在于使用算术技巧或条件移动指令来选择正确的结果(旧值或新乘积),从而避免依赖于时间的分支。对于秘密指数的每一位,CPU 现在都执行相同的指令序列:一次平方、一次乘法、一次选择。时间差异随之消失。

同样,为了防御针对 AES 的缓存攻击,不能简单地以巧妙的“缓存无关”(cache-oblivious)布局重新排列 T-表。缓存无关算法旨在优化平均情况下的性能,而不是提供恒定时间安全性。真正的修复方法更为彻底:完全消除依赖于秘密的内存访问。这可以通过​​比特切片​​(bit-sliced)实现来完成,它重新设计算法,使其仅在寄存器上使用基本的按位逻辑运算(AND、XOR 等),而这些运算的时间是与数据无关的。

操作系统:数字守护者

操作系统作为共享硬件资源的管理者,可以在缓解侧信道(尤其是在不同进程之间)方面发挥关键作用。

为了挫败利用分支预测器的攻击,操作系统可以采取直接方法:在切换安全上下文时,它可以发出一条特殊指令来​​刷新​​(flush)预测器的状态,清除任何带有秘密痕迹的历史记录。这会带来性能成本——新进程以一个“冷”预测器启动,会遭受更多错误预测——但它有效地关闭了该信道。

没有精确的秒表,时间攻击就毫无用处。操作系统与硬件合作,可以通过​​降低​​提供给非特权用户程序的高精度计时器的​​分辨率​​来削弱攻击者的工具。例如,如果一次缓存未命中产生大约 11 纳秒的时间信号,操作系统可以将计时器量化,使其仅以(比如说)50 纳秒的增量报告数值。微小的信号被淹没在量化噪声中,在单次测量中变得无法检测,而操作系统内核仍保留其自身任务所需的高精度访问权限。

硬件:锻造不可变机器

最稳健但也是最昂贵的解决方案是直接在硅片中实现的。

有些是简单的配置更改。由非规格化浮点数引起的时间泄露可以通过启用特殊的处理器模式来消除,例如​​刷新到零​​(Flush-to-Zero, FTZ),该模式将这些有问题的数字视为零,使所有操作都保持在快速路径上,但代价是牺牲一些数值精度。

一种更激进的硬件方法是重新设计逻辑本身,使其本质上具有恒定功耗。在​​双轨逻辑​​(dual-rail logic)中,每个逻辑比特由两条物理线路表示。逻辑“1”可能由线对 (1,0) 表示,逻辑“0”由 (0,1) 表示。电路的设计使得在每个时钟周期内,线对中恰好有一条线路发生跳变。这确保了比特翻转的总数,从而功耗,是恒定的,并且完全与正在处理的数据无关。然而,这种安全性带来了惊人的代价:这样的设计可能使芯片面积和功耗增加一倍以上,同时性能减半。这有力地证明了安全性可能要求的极端权衡。

泄露的度量

我们可以超越对泄露的定性描述,使用信息论的语言对其进行形式化量化。侧信道 LLL 揭示的关于密钥 KKK 的信息量由​​互信息​​(mutual information) I(K;L)I(K; L)I(K;L) 给出,单位是比特。I(K;L)=4.3I(K; L) = 4.3I(K;L)=4.3 比特意味着观察泄露已将攻击者对密钥的不确定性降低了相当于直接获知 4.3 比特密钥的程度。

系统中的噪声和抖动会减少每次观察泄露的信息量。一个依赖于秘密的流水线停顿可能会产生一个干净的 4 周期时间差。但如果系统抖动增加了 ±3 周期的随机噪声,那么“0”比特和“1”比特的时间分布就会重叠。攻击者再也无法通过单次测量来确定秘密。信道变得嘈杂,单次泄露的信息可能只有零点几比特,比如 0.35 比特。但即使是小数比特的泄露也是泄露;通过足够多的观察,攻击者可以平均掉噪声并恢复秘密。

侧信道的故事就是计算的物理本质的故事。它揭示了我们的数字世界并非一个纯逻辑的抽象领域,而是根植于并受制于物理定律。保卫这个世界需要对从算法设计到单个晶体管中电子流动的整个系统堆栈有深入、多层次的理解。这是一场在抽象与物理之间、安全与性能之间、以及对隐私的渴望与自然界不可抗拒的泄密倾向之间的优美而持续的对话。

应用与跨学科联系

在了解了信息如何通过非预期途径泄露的原理之后,我们可能会倾向于将这些侧信道视为一种小众的好奇心,一系列巧妙但孤立的技巧。事实远非如此。机器中的幽灵并非局限于一个房间;它萦绕在我们计算世界的每一个层面,从最抽象的算法到振动的硅片,再到连接我们的网络。要真正领会这一思想的力量和普遍性,我们必须将其视为一种审视计算本质的新视角——一座连接纯净逻辑世界与其所处的混乱物理现实的桥梁。

软件的泄露抽象

我们常常认为软件是纯粹的逻辑,一个由抽象数据结构和算法组成的世界。我们用大 O 符号分析其效率,却忘记了“O”代表“数量级”,这是一种简化,它丢弃了那些可能泄露我们秘密的物理常数和真实世界的时间。

想象一下像桶排序这样的简单排序算法。其优雅之处在于先将项目分配到桶中再进行排序。理论上,其性能取决于输入规模。实际上,其精确执行时间与数据如何分布密切相关。如果数据聚集在一起,某些桶会非常满,子排序步骤就会花费更长的时间。一个监控对“秘密”数据集进行排序总耗时的观察者,因此可以推断出该数据底层统计分布的属性,例如它是均匀的、倾斜的,还是聚集在两端。算法的时间特征成了数据形态的惊人清晰的回响。

这个原理延伸到了驱动我们世界的复杂数据结构中。考虑 B-树,它是大多数数据库(包括那些存储敏感加密密钥的数据库)背后的主力。为了保持平衡和高效,B-树偶尔会对其节点执行昂贵的“分裂”操作。这种分裂只在节点变满时发生。而节点的满溢程度又取决于其所代表的密钥范围内存储的数据密度。攻击者通过在不同范围内插入“探测”密钥并计时操作,可以描绘出数据库的结构。一次缓慢的插入意味着发生了分裂,这又意味着该区域预先存在高密度的秘密密钥。数据结构维护的逻辑必要性变成了一个物理时间信号,泄露了它本应保护的秘密的统计地图。

操作系统(OS),作为所有软件和硬件的总管,是这类泄露抽象的更丰富来源。它的功能是为性能、效率和便利而设计的,但正是这种复杂性创造了无数非预期的通信信道。

  • ​​内存优化器中的间谍:​​ 现代操作系统使用像内核同页合并(Kernel Samepage Merging, KSM)这样的巧妙技巧来节省内存。KSM 会定期扫描系统,找到属于不同进程的相同内存页,并将它们合并成一个单一的、共享的、写时复制(copy-on-write, COW)页。攻击者可以利用这一点,构造一个内存页,其内容是他们想要与受害者秘密页进行比对的内容。如果攻击者随后尝试写入自己的页面,并且写入是瞬时的,他们就知道自己的页面是唯一的。如果写入明显变慢,那是因为操作系统必须执行写时复制,这揭示了该页面曾被合并——因此其内容与受害者的秘密页面相同。这种优化成了一个强大的比较秘密的“神谕”(oracle)。缓解这种情况需要打破优化的确定性,例如,通过随机化 KSM 的扫描计划,将确定性变为仅仅是一种概率。

  • ​​作为帮凶的调度器:​​ 程序在哪里运行和它做什么同样重要。操作系统的调度器中的 processor affinity(处理器亲和性)设置,允许一个进程被“钉”在特定的 CPU 核心上,这可以被武器化。如果一个受害者进程被钉在核心 0 上,攻击者可以使用硬亲和性(hard affinity)也将自己的进程钉在核心 0 上。这保证了他们将在相同的物理硬件上运行,共享像一级缓存这样的微架构资源,为侧信道攻击创造了一个完美的实验室。一个明智的操作系统可以通过使用 soft affinity(软亲和性)来缓解这种情况,将攻击者的请求视为一种偏好而非命令。通过在每个时间片中将攻击者随机分配到任何可用核心,操作系统将共存的概率从确定性降低到仅仅是 1/N1/N1/N(对于 NNN 个核心),从而大幅降低信息信道的带宽,尽管不能完全消除它。

这些例子揭示了一个深刻的真理:软件并非在真空中运行。它的逻辑流在时间和空间上创造了一个物理足迹,一个可以被测量和解码的足迹。

来自硅与钢的低语

当我们从软件的抽象层向下深入,低语声变得更响。执行我们命令的硬件本身就是一曲物理过程的交响乐,每一个过程都是潜在的泄露源。

现代 CPU 是复杂性的奇迹,充满了为加速计算而设计的缓存、预测器和其他共享资源。当攻击者和受害者共享一个 CPU 核心时,他们就像处在一个嘈杂拥挤的房间里。一个人的行为会产生另一个能感觉到的振动。这就是微架构侧信道的基础。例如,将虚拟内存地址转换为物理地址的过程由一系列缓存加速,包括页漫游缓存(Page Walk Cache, PWC)。当操作系统为了节省内存在进程间共享一个软件库时,它可能无意中导致它们使用相同的物理页表。攻击者随后可以仔细地访问内存以填满共享的 PWC,然后通过计时自己随后的访问,检测出哪些条目被受害者的活动所驱逐,从而揭示有关受害者内存访问模式的信息。

泄露并不仅限于 CPU 的内部逻辑,它会向外辐射。你的手机,即使没有散热风扇,也不是静音的。它的处理器使用动态电压和频率调整(Dynamic Voltage and Frequency Scaling, DVFS)来节省电力,对“重”任务运行得快,对“轻”任务运行得慢。这直接将计算的性质与它所花费的墙上时钟时间联系起来,创造了一个时间信道。此外,启用 DVFS 的电源管理电路包含电感和电容等电子元件。随着 CPU 功耗随工作负载变化,这些元件会以与功耗相关的频率振动,产生微弱的“线圈啸叫”(coil whine)。这种由依赖于秘密的工作负载调制的声学发射,可以被设备自身的麦克风拾取,从而将手机变成一个针对自身的窃听设备。

这个问题的规模随着我们机器的规模而增长。在具有非统一内存访问(Non-Uniform Memory Access, NUMA)架构的大型多插槽服务器中,访问远程处理器上的内存比访问本地内存要慢。连接处理器的互连网络是一个共享资源。如果一个插槽上的受害者进程开始一项使用远程内存的内存密集型任务,它会在互连网络上产生流量。另一个插槽上的攻击者仅通过计时自己的远程内存访问就可以检测到这种增加的流量。受害者的活动在数字高速公路上造成了“交通堵塞”,攻击者测量由此产生的延迟,从而泄露了有关受害者依赖秘密的行为的信息,而从未直接共享一个字节的内存。

网络、密码学与量子前沿

侧信道分析的原理不仅限于单台计算机。它们延伸到网络和最前沿的物理学领域。当进程通过远程过程调用(Remote Procedure Calls, RPC)在网络上通信时,它们会产生模式。恶意客户端不仅可以在其消息的内容中编码信息,还可以在消息的到达时间和大小上编码信息。一系列具有精心选择的到达间隔或有效载荷大小的 RPC 可以向一个串通的观察者传输秘密消息,完全绕过传统的安全监控。缓解措施涉及流量整形:将所有消息填充到恒定大小,并重新计时使其按固定间隔发送,通过使流量模式统一且不含信息来消除信道。这是流量分析中经典的猫鼠游戏,也是密码学的一个核心概念。

也许最令人震惊的跨学科联系来自量子力学的世界。像 BB84 这样的量子密钥分发(Quantum Key Distribution, QKD)协议,理论上是“无条件安全”的,因为它们基于基本的物理定律。试图测量量子态的窃听者不可避免地会扰乱它,从而暴露自己的存在。但如果窃听者忽略量子信道,转而攻击 Alice 和 Bob 用于后处理的经典计算机呢?这些经典硬件执行纠错和隐私放大,其功耗与其处理的数据成正比——例如,一个密钥块的汉明权重(‘1’的数量)。通过在 Alice 的硬件附近放置探头并测量其功耗波动,窃听者可以了解到“秘密”密钥的统计属性。这揭示了一个关键教训:安全是整体性的。即使是建立在量子力学完美安全性之上的系统,也可能因其支持电子设备的经典侧信道泄露而受到损害。

从算法的逻辑到电源的嗡鸣,从操作系统的调度器到超级计算机的互联结构,甚至到量子与经典信息的边界,故事都是一样的。计算是物理的。正因为它是物理的,所以它会产生噪声。侧信道分析就是聆听这种噪声的科学,它证明了信息与物理世界之间优美而时而令人畏惧的统一性。它提醒我们,没有完美的黑箱,没有真正无声的机器。只有那些我们尚未学会聆听其低语的系统。