P19.Franklin-Reiter攻击脚本
P19.sage Franklin-Reiter攻击脚本
网上脚本
https://github.com/ValarDragon/CTF-Crypto/blob/master/RSA/FranklinReiter.sage
#sage
# Franklin-Reiter 攻击 RSA。
# 如果两条消息的区别仅在于两条消息之间的已知固定差异
# 并且是在相同的 RSA 模数 N 下进行 RSA 加密的
# 那么就可以恢复它们。
# 输入是模数,已知差异,密文1,密文2。
# Ciphertext 1 对应两个明文中较小的一个。(没有添加固定差异的那个)
def franklinReiter(n,e,r,c1,c2):
R.<X> = Zmod(n)[]
f1 = X^e - c1
f2 = (X + r)^e - c2
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])
# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)
def CoppersmithShortPadAttack(e,n,C1,C2,eps=1/30):
"""
Coppersmith's Shortpad attack!
Figured out from: https://en.wikipedia.org/wiki/Coppersmith's_attack#Coppersmith.E2.80.99s_short-pad_attack
"""
import binascii
P.<x,y> = PolynomialRing(ZZ)
ZmodN = Zmod(n)
g1 = x^e - C1
g2 = (x+y)^e - C2
res = g1.resultant(g2)
P.<y> = PolynomialRing(ZmodN)
# Convert Multivariate Polynomial Ring to Univariate Polynomial Ring
rres = 0
for i in range(len(res.coefficients())):
rres += res.coefficients()[i]*(y^(res.exponents()[i][1]))
diff = rres.small_roots(epsilon=eps)
recoveredM1 = franklinReiter(n,e,diff[0],C1,C2)
print(recoveredM1)
print("Message is the following hex, but potentially missing some zeroes in the binary from the right end")
print(hex(recoveredM1))
print("Message is one of:")
for i in range(8):
msg = hex(Integer(recoveredM1*pow(2,i)))
if(len(msg)%2 == 1):
msg = '0' + msg
if(msg[:2]=='0x'):
msg = msg[:2]
print(binascii.unhexlify(msg))
def testCoppersmithShortPadAttack(eps=1/25):
from Crypto.PublicKey import RSA
import random
import math
import binascii
M = "flag{This_Msg_Is_2_1337}"
M = int(binascii.hexlify(M),16)
e = 3
nBitSize = 8192
key = RSA.generate(nBitSize)
#Give a bit of room, otherwhise the epsilon has to be tiny, and small roots will take forever
m = int(math.floor(nBitSize/(e*e))) - 400
assert (m < nBitSize - len(bin(M)[2:]))
r1 = random.randint(1,pow(2,m))
r2 = random.randint(r1,pow(2,m))
M1 = pow(2,m)*M + r1
M2 = pow(2,m)*M + r2
C1 = Integer(pow(M1,e,key.n))
C2 = Integer(pow(M2,e,key.n))
CoppersmithShortPadAttack(e,key.n,C1,C2,eps)
def testFranklinReiter():
p = random_prime(2^512)
q = random_prime(2^512)
n = p * q # 1024-bit modulus
e = 11
m = randint(0, n) # some message we want to recover
r = randint(0, n) # random padding
c1 = pow(m + 0, e, n)
c2 = pow(m + r, e, n)
print(m)
recoveredM = franklinReiter(n,e,r,c1,c2)
print(recoveredM)
assert recoveredM==m
print("They are equal!")
return True
题目1
from Crypto.Util.number import *
from random import choice
import string
from flag import flag
def getIv(length,chars=string.ascii_lowercase):
return ''.join([choice(chars) for i in range(length)])
p = getPrime(1024)
q = getPrime(1024)
iv = getIv(128)
key1 = bytes_to_long(flag+iv)
key2 = bytes_to_long(iv)
e = 3
print 'n:' + str(p*q)
c1 = pow(key1,e,p*q)
c2 = pow(key2,e,p*q)
print 'c1:' + str(c1)
print 'c2:' + str(c2)
x = key1/key2
y = key1-x*key2
key1=x*key2+y
print 'x:' + str(x)
print 'y:' + str(y)
# output:
n=18099247369280154886617000375109767499806054172740063389012130770186820932961360864498732850525922466534945118800932145228805671351976586517097622365680011651402327925464073182713293531130034756251505774357417055627671229271867926990490595666312835905910514734764729504786992310448996071206128488211439271233843142630939565246707372296583601804184804171689260854956262942235631405717696974169377626396323676395636456740120025184398476594314662368359312356066266921270189494622506635066969735080655725839847984616974215284857408784397344862523720171616739915198953492024993048307867785945156942213152962536432345964739
c1=12278575945470897872640453814770538959516698979717179227690510266529921428552864312660132740788416401327102285180588038083079258311881620201133998229854752124927460819177711379328404288010908880844043596472423294384267295041524633599162192148584399505960857935034928148929492625945646997837039619205559476017169925713468855198646629226970777687397537720214045661626920833445827989359857671018875074072055022703115700566419215341376615131689314020746375076743801434662693872661942545103307966098491064656551141436523806773529181866000500420523710554658948977262516303583655752676734847641890080943847492535926834052488
c2=17408296326028739312453312633484317596943826388625453121732287745283275892186527757287755028016444735036842917880385034442965065523813174163945799579491327454221196284056233455567244848717704030947162883942273297422509937269431814260733969129102074843485655311252111459010777945499431139524012532947251982056639653098247711079544046418704543343537501388589717979520036378098389654456014224822916973106504500942515154126504282811270117380780048894037581126326329800132358724785374395728605324605424194037625702457971360093340866984155213328508506733775129948622882145937096019437059787874064306250117133787681357927186
x=94819009910611490937147710332193973830402125343380796
y=27036298270176650012154148050982037588069778308019261952420224460786523779956477136773576099293451667012578253132502506974471829679519804802324747292357969625762476160905899712303273534268489228000459887114964986912314483751635173113737622875478746013228230937327043213246022641974495178269021953810671692021
解密脚本
因为key2 小于 key1 需要替换下c2 和 c1 的位置
def franklinReiter(n,e,c1,c2,x1,y1):
R.<X> = Zmod(n)[]
f1 = X^e - c2
f2 = (X*x1+ y1)^e - c1
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])
# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)
n=18099247369280154886617000375109767499806054172740063389012130770186820932961360864498732850525922466534945118800932145228805671351976586517097622365680011651402327925464073182713293531130034756251505774357417055627671229271867926990490595666312835905910514734764729504786992310448996071206128488211439271233843142630939565246707372296583601804184804171689260854956262942235631405717696974169377626396323676395636456740120025184398476594314662368359312356066266921270189494622506635066969735080655725839847984616974215284857408784397344862523720171616739915198953492024993048307867785945156942213152962536432345964739
c1=12278575945470897872640453814770538959516698979717179227690510266529921428552864312660132740788416401327102285180588038083079258311881620201133998229854752124927460819177711379328404288010908880844043596472423294384267295041524633599162192148584399505960857935034928148929492625945646997837039619205559476017169925713468855198646629226970777687397537720214045661626920833445827989359857671018875074072055022703115700566419215341376615131689314020746375076743801434662693872661942545103307966098491064656551141436523806773529181866000500420523710554658948977262516303583655752676734847641890080943847492535926834052488
c2=17408296326028739312453312633484317596943826388625453121732287745283275892186527757287755028016444735036842917880385034442965065523813174163945799579491327454221196284056233455567244848717704030947162883942273297422509937269431814260733969129102074843485655311252111459010777945499431139524012532947251982056639653098247711079544046418704543343537501388589717979520036378098389654456014224822916973106504500942515154126504282811270117380780048894037581126326329800132358724785374395728605324605424194037625702457971360093340866984155213328508506733775129948622882145937096019437059787874064306250117133787681357927186
x=94819009910611490937147710332193973830402125343380796
y=27036298270176650012154148050982037588069778308019261952420224460786523779956477136773576099293451667012578253132502506974471829679519804802324747292357969625762476160905899712303273534268489228000459887114964986912314483751635173113737622875478746013228230937327043213246022641974495178269021953810671692021
e=3
key2=franklinReiter(n,e,c1,c2,x1,y1)
print(key2)
print(key2*x1+y1)
#6888963054258642613740325434330669608753226058634053294961493623175402123423076765486521793459129361281449088315708197565085083193444886554420466104040516489271824213587620932188993548052848705998448234910002066319419375438874205309976091920990411697914875778848108746628535295745926285102414338027810783987711072435382043887546827768330700843751035424140257393
#flag{98dd715f2e03fe16}
题目2
from secret import flag
from Crypto.Util.number import *
m1 = bytes_to_long(flag)
N = getPrime(512)*getPrime(512)
e = 17
c1 = pow(m1, e, N)
a = getRandomNBitInteger(512)
b = getRandomNBitInteger(512)
m2 = a*m1 + b
c2 = pow(m2, e, N)
print(N, a, b, c1, c2, sep="\n")
n=51296885372346449295388453471330409021784141081351581975478435681552082076338697136130122011636685327781785488670769096434920591920054441921039812310126089859349902066456998315283909435249794317277620588552441456327265553018986591779396701680997794937951231970194353001576159809798153970829987274504038146741
a=13256631249970000274738888132534852767685499642889351632072622194777502848070957827974250425805779856662241409663031192870528911932663995606616763982320967
b=12614470377409090738391280373352373943201882741276992121990944593827605866548572392808272414120477304486154096358852845785437999246453926812759725932442170
c1=18617698095122597355752178584860764221736156139844401400942959000560180868595058572264330257490645079792321778926462300410653970722619332098601515399526245808718518153518824404167374361098424325296872587362792839831578589407441739040578339310283844080111189381106274103089079702496168766831316853664552253142
c2=14091361528414093900688440242152327115109256507133728799758289918462970724109343410464537203689727409590796472177295835710571700501895484300979622506298961999001641059179449655629481072402234965831697915939034769804437452528921599125823412464950939837343822566667533463393026895985173157447434429906021792720
解题脚本
def franklinReiter(n,e,c1,c2,a,b):
R.<X> = Zmod(n)[]
f1 = X^e - c1
f2 = (X*a+ b)^e - c2
# coefficient 0 = -m, which is what we wanted!
return Integer(n-(compositeModulusGCD(f1,f2)).coefficients()[0])
# GCD is not implemented for rings over composite modulus in Sage
# so we do our own implementation. Its the exact same as standard GCD, but with
# the polynomials monic representation
def compositeModulusGCD(a, b):
if(b == 0):
return a.monic()
else:
return compositeModulusGCD(b, a % b)
n=51296885372346449295388453471330409021784141081351581975478435681552082076338697136130122011636685327781785488670769096434920591920054441921039812310126089859349902066456998315283909435249794317277620588552441456327265553018986591779396701680997794937951231970194353001576159809798153970829987274504038146741
a=13256631249970000274738888132534852767685499642889351632072622194777502848070957827974250425805779856662241409663031192870528911932663995606616763982320967
b=12614470377409090738391280373352373943201882741276992121990944593827605866548572392808272414120477304486154096358852845785437999246453926812759725932442170
c1=18617698095122597355752178584860764221736156139844401400942959000560180868595058572264330257490645079792321778926462300410653970722619332098601515399526245808718518153518824404167374361098424325296872587362792839831578589407441739040578339310283844080111189381106274103089079702496168766831316853664552253142
c2=14091361528414093900688440242152327115109256507133728799758289918462970724109343410464537203689727409590796472177295835710571700501895484300979622506298961999001641059179449655629481072402234965831697915939034769804437452528921599125823412464950939837343822566667533463393026895985173157447434429906021792720
e=17
m=franklinReiter(n,e,c1,c2,a,b)
print(m)
print(hex(m))
#0x666c61677b61353933353931612d333734392d636335322d306332372d6538393766616332633936377d