流密码MTP多次密码本攻击

文章讨论了ManyTimePad加密方法在重复使用密钥时的安全风险,通过频率分析和密文之间的异或关系,介绍了一种攻击策略来破解部分密文,揭示了空格在解密中的关键作用。

Exp2 Theory: Many Time Pad (MTP)多次使用流密码

参考实验代码:

密码学实验一:Many Time Pad(多次使用流密码)_ustcsse2019-lee的博客-优快云博客

参考原理:

Many-Time-Pad 攻击

OTP是无条件安全的:即使攻击者拥有无限的计算资源,都不可能破译OTP加密的密文。探索在使用一次一密的方法加密时,密钥被重复使用时的已知密文攻击方法。

在这里插入图片描述

题目:如下所示是 11 个使用同一个密钥按照 one time pad 方法进行加密得到的密文。请使用前 10 个密文进行分析,并对目标密文进行解密。其中消息(明文)是[a-zA-Z]以及空格组成的字符,使用 ascii 编码(十进制),密文使用 hex 编码(字符的ascii码值的16进制表示)。

密文 = 明文 ⊕ 密钥 密文 1 ⊕ 密文 2 = 明文 1 ⊕ 明文 2 ⊕ 密钥 ⊕ 密钥 = 明文 1 ⊕ 明文 2 \text{密文}=\text{明文}\oplus \text{密钥} \\ \text{密文}_1\oplus \text{密文}_2=\text{明文}_1\oplus \text{明文}_2\oplus \text{密钥}\oplus \text{密钥}=\text{明文}_1\oplus \text{明文}_2 密文=明文密钥密文1密文2=明文1明文2密钥密钥=明文1明文2

上述运算表明两个密文的异或,等于对应明文的异或。这是很危险的性质,高明的攻击者可以通过频率分析,来破译这些密文。如果字符串C1异或上其他所有密文可能得到以下内容,只保留英文字符,其余字符以 “.” 代替。

可以观察到,有些列上有大量的英文字符,有些列一个英文字符都没有。

🐒ASCII码表

ASCII 全称为 ( American Standard Code for Information Interchange),简单的说,就是用 7 位二进制 ( 即 十进制表示为 0 到 127 ) 去编码我们生活中常见的数字,大小写字母。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ascii 码表在 Linux 下可以通过 man ascii 指令查看。它的性质有:

  • 0x20 是空格。 低于 0x20 的,全部是起特殊用途的字符; 0x20~0x7E 的,是可打印字符。
  • 0x30~0x39 是数字 0,1,2...9
  • 0x41~0x5A 是大写字母 A-Z0x61~0x7A 是小写字母 a-z.

💡 存在一个至关重要的规律:小写字母 xor 空格,会得到对应的大写字母;大写字母 xor 空格,会得到小写字母。所以如果 x ⊕ y x\oplus y xy得到一个英文字母,那么 x , y x,y x,y中的某一个有很大概率是空格。再来回头看上面密文C1 xor 其他密文——也就等于明文M1 xor 其他明文,如果第col列存在大量的英文字母,可以猜测 M 1 [ c o l ] M_1[col] M1[col]是一个空格。那一列英文字母越多,把握越大。如果M1的第col列是空格,则有: M i [ c o l ] = M 1 [ c o l ] ⊕ M i [ c o l ] ⊕ M 1 [ c o l ] = M 1 [ c o l ] ⊕ M i [ c o l ] ⊕ 0 x 20 M_i[col]=M_1[col] \oplus M_i[col] \oplus M_1[col] = M_1[col] \oplus M_i[col] \oplus 0x20 Mi[col]=M1[col]Mi[col]M1[col]=M1[col]Mi[col]0x20,也就是只要知道某个字符串C1的某一位是空格,就可以恢复出所有明文在这一列的值。恢复过程为: M i [ c o l ] = C 1 [ c o l ] ⊕ C i [ c o l ] ⊕ 0 x 20 M_i[col]=C_1[col] \oplus C_i[col] \oplus 0x20 Mi[col]=C1[col]Ci[col]0x20

攻击

攻击过程显而易见:对于每一条密文 C i C_i Ci,去异或其他所有10条密文。然后计数异或结果中每一列有多少个英文字符,作为 M i M_i Mi在这一位是空格的评分。然后记录前10条密文空格评分为10~6处的下标,每一轮依次使用前10条密文,根据 M i [ c o l ] = C 1 [ c o l ] ⊕ C i [ c o l ] ⊕ 0 x 20 M_i[col]=C_1[col] \oplus C_i[col] \oplus 0x20 Mi[col]=C1[col]Ci[col]0x20恢复第11条密文相应下标处的值,一共进行5轮,观察恢复过程。最后对明文结果进行修正获得 M i M_i Mi,同时可得到密钥 k e y = M i ⊕ C i key=M_i \oplus C_i key=MiCi,使用密钥可获得此后任意一条密文对应的明文。

在这里插入图片描述

  • 代码示例(Linux):

在这里插入图片描述
在这里插入图片描述

将明文、密文和密钥都转化为16进制整数, 密文 = 明文 ⊕ 密钥 密文=明文 \oplus 密钥 密文=明文密钥

两个长度不同的16进制字符串进行异或时,会将长度较短的字符串前面补0与长字符串长度一致,任何数与0异或后结果不变。例如16进制111异或:1 ^ 11 = 00000001 ^ 00010001 = 00010000 = (16)d = (10)h。

由于只有一个密钥,当明文长度<密钥长度时,密文长度=密钥长度;当明文长度>密钥长度时,密文长度=明文长度。即不能断言密文长度等于明文长度。由上述示例可以看出:当两个16进制字符串长度不同时(令长字符串长为L,短字符串长为l),在结果中会保留长字符串前L-l位,然后对两个字符串的后l位异或,追加到前L-l位后。即长字符串的前L-l位并没有和短字符串实际值异或,而是和0异或,没有用于判断是否为空格的参考价值。

综上所述,当两个密文长度不同时,应当对较长的密文从第0位开始截取长度较短的密文长度的字符串,然后进行异或分析空格位置。此题要分析第11个密文对应的明文,则其他密文长度一定都不小于该密文,所以可以在初始时都截取前10个密文的后l个字符。

问题记录:以上处理方法基于将16进制整数都转换为10进制整数后再进行异或,但是发现并不能这样处理,因为会违背明文是字符串而不是整数的本意。所以需要将16进制字符串中的每2个字符转换为ascii码(即每2个16进制字符对应明文/密文字符串中的一个字符),需要注意bytes类型没有内置的__xor__函数,所以不能直接使用^进行异或,可以依次对两个bytes类型中的对应的每个ascii码进行异或。【binascii.unhexlify()将16进制字符串转化为字节数组bytes类型,字节数组中的每一个元素等于实际字符串中对应每一个字符的ascii码,每两位十六进制字符对应一个ascii码】

MTP(Multiple-Time Programmable)逻辑器件是一种非易失性存储技术,允许用户在制造后多次对器件进行编程和擦除[^1]。与一次性可编程(OTP, One-Time Programmable)器件不同,MTP器件支持多次更新配置数据,从而提高了设计灵活性和后期修改能力。 ### 技术原理 MTP逻辑器件通常基于浮栅晶体管(Floating Gate Transistor)或电荷陷阱存储器(Charge Trap Flash, CTF)技术实现。其核心原理是通过控制浮栅中的电荷状态来改变晶体管的阈值电压,从而实现数据的存储与读取。 - **编程操作**:通过施加高压使电子注入浮栅,改变晶体管的导通状态。 - **擦除操作**:施加反向高压使电子从浮栅中释放,恢复原始状态。 - **读取操作**:通过检测晶体管的导通特性来判断存储状态。 由于MTP器件的编程/擦除次数有限(通常在1000次左右),因此其耐久性介于OTP和Flash之间。 ### 应用场景 MTP技术广泛应用于需要一定灵活性但又不需频繁更新配置的场景中,主要包括: - **嵌入式系统配置存储**:用于存储系统启动参数、密钥或校准数据。 - **现场可编程门阵列(FPGA)配置存储**:部分FPGA使用MTP作为配置存储单元,允许用户在不同功能之间切换。 - **安全芯片中的密钥存储**:MTP可用于安全存储加密密钥,防止非法读取。 - **工业控制与通信设备**:用于存储固件、校准数据或设备标识信息。 ### 优势与局限 **优势**: - 支持多次编程,灵活性高于OTP。 - 编程后数据非易失,无需持续供电。 - 与标准CMOS工艺兼容,集成度高。 **局限**: - 编程/擦除次数有限,通常在1000次以内。 - 编程速度较慢,需高压支持。 - 存在一定的面积开销和功耗问题。 ### 示例代码(模拟MTP存储操作) 以下是一个简化的MTP存储操作模拟代码,用于演示其基本行为: ```python class MTPMemory: def __init__(self, size): self.memory = [0] * size # 初始化为全0状态 self.erase_count = [0] * size # 每个单元的擦除次数 def program(self, address, value): if self.memory[address] == 0: self.memory[address] = value print(f"Address {address} programmed to {value}") else: print(f"Address {address} already programmed. Erase first.") def erase(self, address): if self.erase_count[address] < 1000: self.memory[address] = 0 self.erase_count[address] += 1 print(f"Address {address} erased.") else: print(f"Address {address} has reached max erase cycles.") def read(self, address): return self.memory[address] # 使用示例 mtp = MTPMemory(16) mtp.program(0, 1) print("Read address 0:", mtp.read(0)) mtp.erase(0) print("Read address 0 after erase:", mtp.read(0)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值