题目:(BUUCTF在线评测 (buuoj.cn))
共模攻击
前提:有两组及以上的RSA加密过程,而且其中两次的m和n都是相同的,那么就可以在不计算出d而直接计算出m的值。
设模数为n,两个用户的公钥分别为e1和e2,且e1和e2互素,明文为m,密文分别为c1和c2。在已知e1,e2,n,c1,c2的情况下,推理过程如下:
c1 ≡ m^e1 (mod n) ,c2 ≡ m^e2 (mod n)
从而c1 * c2 ≡ m^(e1+e2)(mod n),这里求出的m需要开根号,并不好。注意到e1和e2互素,即(e1,e2)=1,所以存在整数s,t,使得s * e1+t * e2=1,这样就可以把m的次方化为1,利用扩展欧几里得算法求出s,t,由此可得c1^s * c2^t ≡ m^(s * e1+t * e2)(mod n) ≡ m (mod n),推出m ≡ c1^s * c2^t (mod n)
python代码实现如下:
#共模攻击
import libnum
e1 = 11187289
c1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
e2 = 9647291
c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
def ext_euclid(a, b):
if b == 0:
return 1, 0, a
else:
x, y, q = ext_euclid(b, a % b) # q = gcd(a, b) = gcd(b, a%b)
x, y = y, (x - (a // b) * y)
return x, y, q
r,s,q = ext_euclid(e1,e2)
m = (pow(c1,r,n)*pow(c2,s,n))%n
print(libnum.n2s(m))