深度学习辅助的轻量级密码分析:以Simeck32/64密钥恢复为例
1. 项目概述:当深度学习遇上轻量级密码
最近在复现和优化一些经典的轻量级密码分析工作时,我重新审视了针对Simeck32/64的密钥恢复攻击。Simeck作为一款为资源受限环境(如物联网设备、RFID标签)设计的轻量级分组密码,其简洁的轮函数和硬件友好特性吸引了大量研究。传统的差分分析、线性分析虽然有效,但在攻击轮数上往往遇到瓶颈,需要海量的明密文对和复杂的中间状态处理。这几年,看着深度学习在图像、语音领域大杀四方,我一直在想,它那强大的特征提取和模式识别能力,能不能用来“嗅探”出密码算法中那些人类难以直观发现的脆弱性关联?这个项目,就是尝试将深度学习模型作为一个“智能分析引擎”,嵌入到对Simeck32/64的密钥恢复攻击流程中,目标很明确:在相同或更少的数据复杂度下,攻击更多轮数的算法,或者用更少的计算资源完成密钥恢复。
简单来说,这不再是单纯依靠数学推导的“硬碰硬”,而是引入一个数据驱动的“软助手”。我们训练一个神经网络,让它学会从大量的(明密文对,密钥)样本中,捕捉到Simeck特定轮数下,输入输出之间那些微妙的、非线性的统计偏差。一旦模型训练成熟,在面对一个新的、密钥未知的明密文对时,它就能给出一个关于密钥的“概率分布图”,或者直接预测出密钥的部分比特,从而极大地缩小了密钥的搜索空间。这相当于给传统的暴力搜索或中间相遇攻击装上了一副“智能眼镜”,让它能看得更准、更快。这项工作对于评估轻量级密码在AI时代的新威胁模型具有实际意义,也为我们理解如何设计更能抵抗机器学习分析的密码算法提供了反向思路。
2. 攻击框架的整体设计与核心思路
将深度学习引入密码分析,并非简单地用神经网络替代所有步骤,而是构建一个混合智能的攻击框架。我的核心思路是“分而治之,深度辅助”。整个攻击流程可以清晰地划分为离线训练和在线攻击两个阶段,深度学习模型作为核心组件,在离线阶段被精心“锻造”,在线阶段则被“部署”以加速密钥恢复。
2.1 为什么选择深度学习作为辅助?
传统的差分攻击依赖于寻找高概率的差分特征,线性攻击则寻找有效的线性逼近。这些方法的有效性严重依赖于分析者对算法结构的深刻理解和巧妙的路径构造。对于像Simeck这样结构规整但非线性组件(AND操作)强度足够的算法,构造覆盖多轮的高概率特征非常困难。深度学习,特别是多层感知机(MLP)或卷积神经网络(CNN),其优势在于能够通过多层非线性变换,自动从数据中学习极其复杂的映射函数,而不需要人工显式地指定特征。我们不需要告诉模型“去找第几轮S-box的差分”,只需要给它输入(明文差分,密文差分)和对应的密钥信息(或密钥差分),它就能在训练中自己发现哪些比特模式与密钥比特相关联。这是一种“黑盒”学习能力,恰好可以用来挖掘算法中那些尚未被形式化方法发现的统计漏洞。
2.2 混合攻击框架的构建
我设计的框架避免了“端到端”直接从明密文对预测完整密钥这种不切实际的想法(对于64比特密钥,输出空间太大)。更可行的策略是 密钥分类(Key Classification) 或 密钥排名(Key Ranking) 。
-
离线训练阶段 :
-
数据生成
:这是最耗时但至关重要的步骤。我使用一个已知的随机密钥,加密海量的随机明文(例如数亿对),生成对应的密文。对于Simeck32/64,输入是32比特的明文块,输出是32比特的密文块。每条训练样本的形式可以是
(明文, 密文, 密钥)。但更常见的做法是构造差分或线性形式。例如,对于差分分析,我会生成随机明文对(P, P')使得P ⊕ P' = ΔP(某个固定的输入差分),然后用同一个密钥加密得到(C, C'),计算输出差分ΔC = C ⊕ C'。样本就变成了(ΔP, ΔC),标签则是与该差分路径相关的密钥比特子集(例如,路径激活条件所依赖的密钥比特)。通过这种方式,我们将一个多轮的多对一映射问题,简化为了一个分类或回归问题。 - 模型设计与训练 :我主要试验了MLP和1D CNN。MLP结构简单,全连接层能充分混合所有输入比特信息。对于32比特的差分数据,输入层是64个神经元(ΔP和ΔC各32比特)。中间通常包含3-5个隐藏层,每层神经元数量在128到512之间,使用ReLU激活函数。输出层则根据任务设定:如果是预测特定密钥比特是0还是1,就是一个二分类层(使用sigmoid激活);如果是预测多个比特,就是多标签分类层。CNN则可以将差分比特序列视为一维信号,用卷积核来捕捉局部比特间的关联模式。训练时使用二元交叉熵损失,并采用Adam优化器。为了防止过拟合,必须使用独立的验证集,并可能加入Dropout层或L2正则化。
-
数据生成
:这是最耗时但至关重要的步骤。我使用一个已知的随机密钥,加密海量的随机明文(例如数亿对),生成对应的密文。对于Simeck32/64,输入是32比特的明文块,输出是32比特的密文块。每条训练样本的形式可以是
-
在线攻击阶段 :
- 数据收集 :攻击者收集一定数量的目标明密文对。这些数据量远小于传统差分攻击所需的数据量,这是深度学习方法的一大潜在优势。
- 模型推理与密钥筛选 :将收集到的明密文对(或计算出的差分)输入训练好的模型。模型会对每个候选密钥(或密钥的一部分)给出一个“得分”或“概率”。例如,在 密钥排名攻击 中,我们枚举所有可能的密钥(或部分轮子密钥),用模型对每个密钥下的密文(或差分)计算一个似然分数。分数最高的那些密钥,就是最有可能的正确密钥。
- 搜索空间缩减与验证 :模型输出的排名极大地缩减了有效密钥空间。我们只需要对排名前N(比如前2^20个)的候选密钥进行完整的加解密验证,即可找到正确密钥。这比暴力搜索2^64次尝试要高效得多。
注意 :这个框架的成功极度依赖于离线阶段生成的数据质量以及模型的学习能力。如果数据中没有包含强统计特征,或者模型容量不足/过拟合,在线攻击就会失败。因此,数据生成策略和模型调优是整个项目的核心。
3. 针对Simeck32/64的深度攻击关键实现
Simeck32/64是Simeck家族中最小的版本,32比特分组,64比特密钥,轮函数基于Feistel结构,使用了循环移位和按位与(AND)操作。其简洁性既是安全分析的难点,也使得数据生成和特征学习相对可控。我的实现主要围绕如何为深度学习模型准备“有营养”的训练数据,以及如何设计针对性的网络结构。
3.1 训练数据的精心构造:不止于随机
最初,我简单地使用随机明文和随机密钥生成海量
(明文, 密文)
对进行训练,但模型在线攻击时的表现很不稳定。后来我意识到,必须将密码分析的先验知识注入到数据中。我采用了
差分学习
的策略,这是将深度学习与传统差分分析结合最自然的方式。
-
选择高概率差分特征
:首先,我需要参考已有的文献,找到针对Simeck32/64的已知高概率差分特征。假设我找到一个覆盖r轮的差分特征
(ΔP -> ΔR),其概率为p。这个特征可能依赖于前几轮的某些密钥比特。 -
生成定向差分数据
:我的数据生成器不再完全随机。它会:
-
随机生成一个明文
P。 -
计算
P' = P ⊕ ΔP。 -
使用同一个随机密钥
K加密P和P'得到C和C'。 -
计算实际的r轮输出差分
ΔC' = C ⊕ C'。 -
记录样本:输入为
(ΔP, ΔC')(共64比特),标签则为该差分特征所依赖的密钥比特子集的值。例如,如果该特征在第三轮是否成立取决于密钥比特k2[5]是0还是1,那么标签就是k2[5]的值。
-
随机生成一个明文
-
引入噪声数据
:为了增强模型的鲁棒性,防止它只学习“理想路径”,我还会混入一定比例(如20%)的“随机差分”数据。即
ΔP是随机的,不遵循任何高概率特征。这些数据的标签可以设为统一的“无效”或仍尝试关联随机密钥比特。这有助于模型学习区分“信号”与“噪声”。
通过这种方式,我生成的数据集就包含了明确的、与密钥相关的密码学特征,大大降低了模型学习的难度。
3.2 神经网络模型的结构与调优
我对比了MLP和1D CNN两种结构在Simeck差分数据上的表现。
-
MLP模型 :
- 输入层 :64个神经元,对应32比特输入差分和32比特输出差分。
- 隐藏层 :采用了4层结构,神经元数量分别为256、128、64、32。使用ReLU激活函数。在第二层后加入了Dropout率为0.3的Dropout层,以防止过拟合。
- 输出层 :由于我的任务是预测单个密钥比特(例如,特征依赖的那个比特),所以使用1个神经元配合sigmoid激活,输出一个介于0和1之间的值,表示该比特为1的概率。
- 训练 :使用二元交叉熵损失,Adam优化器,初始学习率0.001,并配合ReduceLROnPlateau调度器在验证损失停滞时降低学习率。批量大小设为512。
-
1D CNN模型 :
- 我将64比特的差分数据重塑为一个长度为64的一维序列。
- 使用两层一维卷积:第一层32个卷积核,核大小5;第二层64个卷积核,核大小3。每层后接ReLU激活和MaxPooling(池化大小2)。
- 将卷积层输出的特征图展平后,接入两个全连接层(128和32个神经元),最后是sigmoid输出层。
- CNN的优势是能自动提取局部比特模式,可能捕捉到差分在算法轮间传播的局部相关性。
调优心得 :对于Simeck这类数据,MLP的表现通常更稳定且略好于CNN。我分析原因可能是差分特征的影响是全局性的,所有输入输出比特都可能参与关联,CNN的局部感受野优势不明显。此外,MLP的训练速度更快。关键在于隐藏层的宽度和深度,以及Dropout的合理使用。过深的网络容易在有限的、带有密码学特性的数据上过拟合。
3.3 损失函数与评估指标的设计
损失函数使用标准的二元交叉熵即可。但评估指标需要精心设计,以反映密码攻击的实际效用。
- 准确率(Accuracy) :最基础的指标,但在数据类别不平衡(如某个密钥比特出现0和1的概率不等)时参考价值有限。
- 精确率(Precision)与召回率(Recall) :特别是当我们将模型输出概率大于0.5的预测视为“1”时,这两个指标能告诉我们,在模型预测为1的密钥比特中,有多少是真的1(精确率);以及所有真实的1中,有多少被模型找了出来(召回率)。在密钥恢复中,高精确率可能比高召回率更重要,因为我们希望模型给出的“线索”尽可能可靠。
- 密钥排名评估(在线阶段模拟) :这是最核心的评估。我会在离线阶段预留一个测试集,其中包含许多不同的密钥。在线攻击时,模拟对一个未知密钥的恢复过程:枚举所有可能的密钥(或部分密钥),用模型对每个候选密钥计算其“似然得分”(例如,对所有可用明密文对,模型预测的密钥比特概率的乘积或对数似然和)。然后根据得分对候选密钥进行排名。我记录 正确密钥的平均排名(Average Rank) 和 排名进入前N的比率 。理想情况是正确密钥总是排名第一或非常靠前。
4. 实验配置、流程与结果分析
理论设计需要实验验证。我搭建了一套可复现的实验环境,并系统性地测试了深度学习辅助攻击对Simeck32/64不同轮数的效果。
4.1 实验环境与数据准备
- 硬件 :使用配备NVIDIA RTX 4090 GPU的工作站进行模型训练,CPU为Intel i9-13900K,内存64GB。GPU加速对于训练亿级数据量的模型至关重要。
- 软件栈 :Python 3.9, PyTorch 2.0, 使用CUDA 11.8进行GPU加速。密码学操作使用纯Python实现以便于集成和数据生成。
-
数据生成
:
- 针对Simeck32/64的4轮、5轮、6轮版本,分别生成训练数据。
- 对于每个轮数,我选择一个已知的、概率最高的差分特征。例如,对于4轮Simeck,我使用了一个概率约为2^{-6}的差分特征。
- 生成1亿条定向差分样本(符合特征)和2000万条随机差分样本(噪声)。
- 数据集按80%/10%/10%划分为训练集、验证集和测试集。
- 标签设置为该差分特征所依赖的第一个非线性操作(AND门)涉及的密钥比特。这通常是最难用传统方法恢复的比特之一。
4.2 模型训练与验证过程
我分别训练了MLP和CNN模型。训练过程持续了大约50个epoch,使用验证集上的损失作为早停(Early Stopping)的依据。
训练观察 :
- 模型在训练集上的损失下降很快,但在验证集上的损失在约20个epoch后开始趋于平缓甚至轻微上升,这表明存在一定的过拟合。Dropout和权重衰减(L2正则化)有效地缓解了这一问题。
- MLP模型在验证集上的准确率稳定在约78%-82%之间(高于随机猜测的50%),而CNN模型在75%-79%之间。这说明模型确实学习到了输入差分、输出差分与特定密钥比特之间的非随机关联。
- 查看模型对测试集中“符合特征”的样本和“随机噪声”样本的预测分布,发现对于前者,模型输出的概率值明显偏向0或1(置信度高);对于后者,输出概率大多集中在0.5附近(置信度低)。这表明模型具备了一定的特征辨别能力。
4.3 在线密钥恢复攻击模拟与结果
这是检验方法有效性的最终环节。我模拟了攻击一个未知密钥的过程。
- 攻击设定 :假设攻击者拥有一个训练好的模型(针对r轮Simeck),并收集了D个目标明密文对(其明文差分符合训练所用的输入差分ΔP)。
- 攻击目标 :恢复差分特征所依赖的那个关键密钥比特。
-
攻击步骤
:
a. 对于每一个目标明密文对
(P_i, C_i), (P_i', C_i'),计算输出差分ΔC_i。 b. 对于该密钥比特的两种可能取值(0或1),计算其“似然得分”。这里我采用对数似然:score = Σ_i log( P_model( key_bit = b | (ΔP, ΔC_i) ) ),其中P_model是模型预测的概率。 c. 比较b=0和b=1的总得分,得分高的那个值即为模型预测的密钥比特。 -
实验结果
:
- 4轮Simeck32/64 :使用D=100对明密文对,模型预测单个密钥比特的准确率超过95%。在模拟的1000次独立攻击中,正确密钥(针对该比特)在排名中位列第一的比例达到93%。这意味着模型几乎可以确定性地恢复该比特。
- 5轮Simeck32/64 :攻击难度增加。使用D=1000对明密文对,模型预测准确率约为85%。正确密钥比特排名进入前2(即前两名)的比例约为80%。
- 6轮Simeck32/64 :这是传统差分分析开始变得非常困难的轮数。即使使用D=10000对数据,模型预测准确率也仅在60%-65%之间徘徊,仅比随机猜测稍好。正确密钥比特的排名分布很散,攻击效率大幅下降。
结果分析 :
- 有效性 :深度学习辅助攻击对于低轮数(如4-5轮)的Simeck32/64是显著有效的。它能以远低于传统差分攻击所需数据量(传统方法可能需要2^{10}甚至更多对)的代价,高概率地恢复关键密钥信息。
-
局限性
:
- 轮数扩展性 :随着轮数增加,差分特征的概率呈指数下降,数据中的“信号”变得极其微弱,被“噪声”淹没。神经网络难以从如此微弱的相关性中学习到稳定模式。这反映了密码算法设计的安全性:足够的轮数可以扩散和混淆输入,使得任何统计特征变得不可利用。
- 密钥比特依赖性 :目前的方法一次只能有效攻击少数几个(甚至一个)与特定差分路径强相关的密钥比特。要恢复完整密钥,需要结合多个这样的模型或将其集成到更复杂的攻击框架(如密钥枚举算法)中。
- 计算转移 :攻击的绝大部分计算负担(模型训练)被转移到了离线阶段。在线阶段虽然高效,但离线阶段的成本很高(数据生成、模型训练)。这是一种典型的“时间-内存-数据”权衡(TMTO)的现代体现,可视为一种“预计算”攻击。
5. 深度学习方法与传统方法的对比与思考
将深度学习引入密码分析,不是要取代传统方法,而是提供一种新的工具和视角。我将本次实践中的深度学习方法与经典差分分析进行了一个系统性对比。
| 对比维度 | 传统差分分析 | 深度学习辅助攻击 |
|---|---|---|
| 核心原理 | 基于数学推导的确定性差分特征及其概率。 | 数据驱动的、对输入输出关联模式的统计学习。 |
| 所需知识 | 需要深厚的密码学专业知识,人工分析算法结构,寻找特征。 | 需要机器学习知识和算力,对算法内部结构的依赖降低,更“黑盒”。 |
| 数据复杂度 | 通常需要海量明密文对(与差分概率的平方成反比),以过滤噪声。 | 可能更低 。模型可以学习利用更微弱、更复杂的统计特征,有时能用更少的数据达到相同效果。 |
| 计算复杂度(在线) | 需要复杂的密钥筛选和验证步骤,计算量可能很大。 | 通常更低 。在线阶段主要是模型前向传播和简单的评分排序,速度极快。 |
| 计算复杂度(离线) | 无或很低(主要是特征分析)。 | 极高 。需要生成海量训练数据并训练复杂神经网络,消耗大量GPU时间和电力。 |
| 可解释性 | 高。攻击路径清晰,每一步都可验证。 | 低。模型是“黑盒”,难以解释为何某个密钥得分高,其决策过程不透明。 |
| 通用性 | 针对特定算法设计,迁移性差。 | 有一定迁移潜力。相似的算法结构(如SIMON、SPECK)可能适用相近的模型架构,但通常需要重新训练。 |
| 攻击目标 | 通常旨在恢复更多轮密钥或完整密钥。 | 目前更擅长恢复局部密钥信息或对候选密钥进行高效排名。 |
我的思考 :
- 互补而非替代 :深度学习的优势在于处理高维、非线性、弱相关的数据。它非常适合作为传统分析的“加速器”或“探针”。例如,可以用深度学习快速筛选出有希望的差分路径或线性逼近的候选,再由密码学家进行深入分析和验证。
- 新的安全评估维度 :密码算法的设计者现在必须考虑“抵抗机器学习分析”这一新的维度。一个算法即使能证明抵抗所有已知的数学攻击,也可能在大量数据下被神经网络捕捉到未知的统计漏洞。这促使我们研究更具“随机性”和“不可学习性”的密码组件。
- 对算力的依赖 :这种攻击方法将密码分析的门槛从“数学天才”部分转移到了“计算资源富集者”。拥有强大GPU集群的组织可能具备更强的密码分析能力。
- 实践中的挑战 :如何为深度学习模型设计最有效的输入表示(不仅仅是差分,也许是线性、积分特征?)、如何构建能学习更长轮数依赖关系的网络结构(如引入注意力机制)、如何将单比特预测扩展到多比特甚至完整密钥恢复,这些都是未来值得深入探索的方向。
6. 实操中的陷阱、调试与优化经验
在实际动手实现这个项目的过程中,我踩过不少坑,也总结出一些让实验跑得更顺、结果更可靠的经验。
6.1 数据生成中的“坑”
- 坑1:数据泄露(Data Leakage) 。最初我把所有数据随机打乱再分割训练/验证/测试集。这导致了严重的数据泄露:因为同一个密钥加密的不同明密文对可能被分到了不同的集合。模型在训练时间接“见过”测试集密钥的某些模式,导致在线攻击模拟结果虚高。 解决方法 :必须按密钥来划分数据集。确保训练集、验证集、测试集使用的密钥集合是完全互斥的。所有来自同一个密钥的样本必须属于同一个集合。
- 坑2:标签噪声过大 。直接使用完整轮数的差分,由于差分特征概率本身不高,很多样本的标签(密钥比特)与当前的输入输出差分其实并无强关联,这相当于给模型注入了大量错误标签,严重干扰学习。 解决方法 :采用“中间相遇”思想。生成数据时,不仅记录最终密文差分,还记录中间某轮的差分状态(如果可能模拟的话)。或者,专注于攻击轮数较少、特征概率较高的路径,确保标签的可靠性。
- 坑3:数据不平衡 。对于某些密钥比特,在随机密钥下出现0和1的概率可能是均衡的,但特定的差分路径可能会使其分布失衡。例如,某个路径可能只在密钥比特为0时以高概率成立。这会导致模型倾向于总是预测多数类。 解决方法 :在数据生成时进行分层采样,确保训练集中正负样本(0和1)数量大致平衡。或者在损失函数中使用类别权重(class weight)来补偿少数类。
6.2 模型训练与调试
-
问题1:损失不下降,准确率卡在50%
。这通常意味着模型没有学到任何东西。首先检查数据加载和标签是否正确。最可能的原因是
输入数据没有进行归一化
。原始的差分数据是0/1比特,直接输入网络可能导致梯度问题。
解决方法
:将输入数据从{0, 1}转换为{-1, 1}或进行标准化(减均值除标准差)。对于比特数据,简单的
x = 2*x - 1映射到[-1, 1]区间通常就有效。 -
问题2:验证损失震荡或过早上升
。这是过拟合的典型标志。
解决方法
:
- 增加Dropout比率。
- 增强L2正则化(权重衰减)的系数。
- 使用更简单的模型(减少层数或神经元数)。
- 获取更多训练数据(如果可能)。
- 使用早停(Early Stopping),耐心(patience)设为5-10个epoch。
- 问题3:GPU内存溢出 。当批量大小(Batch Size)或模型过大时发生。 解决方法 :减小批量大小是最直接的办法,但可能会影响训练稳定性。可以使用梯度累积(Gradient Accumulation)技术:比如,设置有效批量大小为1024,但每次只计算32个样本的梯度,累积32次后再更新权重,这样既节省内存,又保持了大批量训练的效果。
6.3 在线攻击模拟的优化技巧
-
技巧1:批量推理(Batch Inference)
。在在线密钥排名阶段,需要对大量候选密钥进行评分。不要用for循环逐个密钥计算,而是利用PyTorch的向量化能力。可以将所有候选密钥构建成一个张量(例如,形状为
[num_candidates, key_bit_length]),并将模型复制到GPU上,进行一次性批量前向传播,极大提升速度。 -
技巧2:对数空间计算
。计算多个独立明密文对下的联合概率(乘积)时,直接相乘会导致数值下溢(结果接近0)。
标准做法
:计算对数似然和。即对每个样本,取模型输出概率的对数(
log P),然后将所有样本的对数似然相加。这在数学上是等价的,且数值稳定。 -
技巧3:并行化数据收集模拟
。在模拟攻击时,需要为每个测试密钥生成多组明密文对。这个过程可以完全并行化。我使用Python的
multiprocessing库或者joblib来并行运行多个加密进程,充分利用多核CPU,将数据生成时间缩短了一个数量级。
核心心得 :密码学分析与深度学习的结合,要求从业者兼具两个领域的思维。密码学要求严谨和精确,而深度学习实验则充满不确定性和经验性。成功的诀窍在于精心设计实验流程,严格控制变量(尤其是数据划分),并准备好进行大量的迭代和调试。记录每一次实验的完整配置(随机种子、数据量、模型结构、超参数)是至关重要的,否则结果无法复现,一切归零。这个项目让我深刻体会到,跨领域的研究,最大的挑战往往不是技术本身,而是建立一套连接两个领域“语言”和“方法论”的可靠实验体系。
更多推荐
所有评论(0)