填充提示攻击:原理、技术分析 简介填充提示攻击是一种针对使用 CBC 模式的分组密码如 AES、DES的侧信道攻击。它于 2002 年由 Serge Vaudenay 首次提出其威力在于即使攻击者不知道加密密钥只要服务器对密文解密后返回“填充是否正确”的反馈攻击者就能在数千次查询内解密任意密文基础知识CBC 模式与 PKCS#7 填充CBC 加密模式CBCCipher Block Chaining模式是常用的分组密码工作模式。加密时每个明文块先与前一个密文块异或再通过分组密码加密解密时每个密文块先解密再与前一个密文块异或得到明文块。加密C_i Encrypt(P_i ⊕ C_{i-1})其中C_0 IV初始向量解密P_i Decrypt(C_i) ⊕ C_{i-1}PKCS#7 填充由于分组密码只能处理固定长度如 16 字节的数据块明文末尾需要填充至块长度的整数倍。PKCS#7 规定填充的每个字节的值都等于填充的字节数n1 ≤ n ≤ 16。例如若差 3 字节则填充0x03 0x03 0x03若恰好为整数倍则填充 16 个0x10。解密时服务器必须检查填充格式是否合法。若无效通常会返回错误如400 Bad Request或500 Internal Server Error若有效则继续处理。这个“是否有效”的差异正是攻击的突破口。前提条件使用 CBC 模式且填充遵循 PKCS#7或类似。攻击者能够截获密文包括 IV并篡改它。存在一个“预言机Oracle”服务器会根据填充是否正确给出不同的响应如不同的错误代码、响应时间差异等。攻击者可以利用这种反馈来判断填充是否有效。攻击者可以反复发送修改后的密文且服务器不会因错误次数过多而封锁。攻击过程要进行攻击的话要有密文数据及iv首先就是根据CBC模式的特点解密时是P_i Decrypt(C_i) ⊕ C_{i-1}然而密钥未知所以Dercypt(C_i)是未知的填充提示攻击就是修改P_i及C_{i-1}以得到Dercypt(C_i)明文其实也是未知的但是根据这个漏洞的特点此时假设明文就填充了一字节修改C_{i-1}倒数第一字节让其与Dercypt(C_i)倒数第一字节异或后结果为0x01也就是一个碰撞的过程碰撞成功服务端就认为填充正确返回正确信息或者状态此时拿碰撞成功的最后一字节与0x01异或就能得到Dercypt(C_i)最后一字节开始碰撞倒数第二字节此时就要假设明文只填充了两字节就要假设明文最后两字节都是0x02首先要把已知的东西修改好再去碰撞。现在已经知道Dercypt(C_i)最后一字节将他和0x02异或此时得到的就是要碰撞C_{i-1}倒数第二字节时的C_{i-1}的最后一字节因为碰撞第二字节时假设明文后两位全是0x02已经知道中间值最后一字节了就可以直接算出要碰撞的最后一字节直接碰撞倒数第二字节就行后续的整个分组也是这么继续要碰撞倒数第n字节就要假设明文填充了0x0n然后将已知的Dercypt(C_i)的倒数n-1字节与0x0n异或得到碰撞时C_{i-1}的倒数n-1字节。这个时候就只需要碰撞倒数第n字节就行最后碰撞完一个分组就能得到一个完整分组的Dercypt(C_i)将其与原始的C_{i-1}进行异或就可以得到明文对于整个密文IV, C1, C2, ..., Cn攻击顺序通常从最后一个块开始依次向前攻击 C_n 时修改 C_{n-1}攻击 C_{n-1} 时修改 C_{n-2}…攻击 C_1 时修改 IVC_0经典漏洞POODLE2014攻击 SSLv3.0 中的 CBC 模式填充通过降级攻击迫使客户端使用 SSLv3.0从而窃取 cookie。Lucky Thirteen2013利用 TLS 解密时的时序差异13 微秒即使服务器返回相同错误也能区分填充是否有效。ASP.NETPadding Oracle2010微软 ASP.NET 框架中的漏洞允许攻击者解密 ViewState 等数据甚至提升权限。这些漏洞都源于一个共同原因服务器对填充错误的响应存在可观测差异。防范措施避免暴露“填充是否有效”的反馈统一错误消息无论填充错误还是 MAC 验证失败都返回相同的通用错误避免差异。使用抗时序攻击的代码确保解密和验证过程的执行时间与输入无关防止时序侧信道。先验证完整性再解密加密后 MAC标准做法是使用HMAC 或 AEAD如 AES-GCMEncrypt-then-MAC先加密再对密文包括 IV计算 MAC。接收方先验证 MAC若无效则直接丢弃不进行解密从而避免触发填充检查。MAC-then-Encrypt或Encrypt-and-MAC可能存在风险故推荐 Encrypt-then-MAC。使用认证加密模式现代加密算法如 AES-GCM、ChaCha20-Poly1305 本身就是认证加密AEAD它们同时提供机密性和完整性从根本上杜绝了填充 Oracle 攻击。限制查询频率对于必须暴露 Oracle 的场景可以设置错误次数阈值当攻击者频繁请求时暂时封锁或增加延迟但这种方法仅作辅助不能作为主要防线。