概念
RSA 共模攻击(Common Modulus Attack)是一种在特定条件下可以利用的 RSA 加密算法的攻击方法。它利用了当多个密文使用同一个 RSA 公钥(即相同的模数 n)进行加密时,可能可以通过密文之间的关系来获取明文信息,而无需知道私钥。
实现原理
必要条件:
- 已知模数
n
- 已知公钥指数
e
- 已知多个密文
C1 C2 ... Cn
- 部分或全部密文的公钥指数
e
之间满足一定的数学关系,例如互为逆元、公因子等
对于明文 m
使用公钥 (n,e)
进行加密得到密文 c
:
c = m e m o d ( n ) c=m^e mod (n) c=memod(n)
已知 RSA 公钥加密的安全基于大整数分解问题的困难性,即给定 n
和 e
,从 n
中提取 p
和 q
的难度。然而,在某些情况下,当多个密文使用相同的 n
和不同的公钥指数 e
进行加密时,可以利用这种公共模数来推导出明文。通过这种方式,攻击者可以计算出原始消息m,即使他们不知道私钥d1和d2。
在实际应用中,这种攻击的可行性取决于多个因素,包括e1和e2的值以及模数n的保密程度。如果e1和e2不互质,那么攻击的难度会增加。此外,如果n是一个大的合数,那么分解n的难度也会增加,从而提高了安全性。
举个栗子1
n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
e1 = 11187289
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2 = 9647291
我们可以根据上面所提及的运算方式得出运算脚本↓↓↓
from gmpy2 import invert
import binasciidef common_modulus_attack(n, c1, c2, e1, e2):"""使用共模攻击解密RSA加密的密文。参数:n (int): RSA模数c1 (int): 第一个密文c2 (int): 第二个密文e1 (int): 第一个公钥指数e2 (int): 第二个公钥指数返回:int: 解密后的明文"""def extended_gcd(a, b):"""扩展欧几里得算法,用于求解两个数的最大公约数及其系数。参数:a (int): 第一个数b (int): 第二个数返回:tuple: (gcd, x, y),其中 gcd 是最大公约数,x 和 y 是满足 ax + by = gcd 的系数"""if b == 0:return a, 1, 0else:gcd, x, y = extended_gcd(b, a % b)return gcd, y, x - (a // b) * y# 使用扩展欧几里得算法计算 e1 和 e2 的最大公约数及其系数gcd, coefficient1, coefficient2 = extended_gcd(e1, e2)# 如果系数为负数,则求模反元素if coefficient1 < 0:coefficient1 = -coefficient1c1 = invert(c1, n)elif coefficient2 < 0:coefficient2 = -coefficient2c2 = invert(c2, n)# 计算解密后的明文plaintext = pow(c1, coefficient1, n) * pow(c2, coefficient2, n) % nreturn plaintext# 给定的参数和密文
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
e1 = 11187289
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e2 = 9647291# 使用共模攻击解密密文
plaintext = common_modulus_attack(n, c1, c2, e1, e2)# 输出解密后的结果
print("解密后的明文(十进制):", plaintext)
print("解密后的明文(ASCII):", binascii.unhexlify(hex(plaintext)[2:]).decode('utf-8'))
数据来源于网络 ↩︎