RSA 进阶 下


低加密指数分解攻击

在 RSA 中 e 也称为加密指数。
由于 e 是可以随意选取的,选取小一点的 e 可以缩短加密时间(比如 e=2,e=3),但是选取不当的话,就会造成安全问题。
由于e很小,当n很大时,\(m^e\)也比n小很多.尝试把c开根号看能否得到明文。

BUUCTF-Dangerous RSA

题目:

#n:  0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793L
#e:  0x3
#c:  0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
so,how to get the message?

思路:
e很小,但是n很大,加密\(c\;=\;m^e\;mod\;n\)

  1. \(m^e\;<\;n\)时,\(c\;=\;m^e\)即对c开方就能得到m
  2. \(m^e\;>\;n\)时,则有\(m^e\;=\;k*n+c\),对k进行爆破

解:

import gmpy2

n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e = 3
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

k = 0
while 1:
    res = gmpy2.iroot(k*n+c,e)
    if(res[1] == True):
        print(bytes.fromhex(hex(res[0])[2:]))
        break
    k += 1

flag{25df8caf006ee5db94d48144c33b2c3b}

低加密指数广播攻击(Hastad攻击)

什么是广播,假如我们需要将一份明文进行多份加密,但是每份使用不同的密钥,密钥中的模数n不同但指数e相同且很小,我们只要拿到多份密文和对应的n就可以利用中国剩余定理进行解密。

低加密指数广播攻击的特点:
加密指数e非常小,一份明文使用不同的模数n,相同的加密指数e进行多次加密,可以拿到每一份加密后的密文和对应的模数n、加密指数e

BUUCTF-RSA5

题目:
image

解:

import gmpy2

e = 65537
n = []
c = []
flag = 0
index = 0

path = 'D:/Downloads/1.txt'#先把文件处理一下
with open(path,'r',encoding='utf-8') as f:
    for line in f.readlines():
        if(line[0] == 'n'):
            n.append(int(line[4:]))
        elif(line[0] == 'c'):
            c.append(int(line[4:]))

for i in range(len(n)):
    if index == 1:
        break
    else:
        for j in range(len(n)):
            if(i!=j):
                p = gmpy2.gcd(n[i],n[j])
                if(p != 1):
                    flag = i
                    index = 1
                    break

n = n[flag]
c = c[flag]
q = n//p
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
m = gmpy2.powmod(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

flag{abdcbe5fd94e23b3de429223ab9c2fdf}

BUUCTF-RSA4

题目:

N = 331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004 
c = 310020004234033304244200421414413320341301002123030311202340222410301423440312412440240244110200112141140201224032402232131204213012303204422003300004011434102141321223311243242010014140422411342304322201241112402132203101131221223004022003120002110230023341143201404311340311134230140231412201333333142402423134333211302102413111111424430032440123340034044314223400401224111323000242234420441240411021023100222003123214343030122032301042243

N = 302240000040421410144422133334143140011011044322223144412002220243001141141114123223331331304421113021231204322233120121444434210041232214144413244434424302311222143224402302432102242132244032010020113224011121043232143221203424243134044314022212024343100042342002432331144300214212414033414120004344211330224020301223033334324244031204240122301242232011303211220044222411134403012132420311110302442344021122101224411230002203344140143044114 
c = 112200203404013430330214124004404423210041321043000303233141423344144222343401042200334033203124030011440014210112103234440312134032123400444344144233020130110134042102220302002413321102022414130443041144240310121020100310104334204234412411424420321211112232031121330310333414423433343322024400121200333330432223421433344122023012440013041401423202210124024431040013414313121123433424113113414422043330422002314144111134142044333404112240344

N = 332200324410041111434222123043121331442103233332422341041340412034230003314420311333101344231212130200312041044324431141033004333110021013020140020011222012300020041342040004002220210223122111314112124333211132230332124022423141214031303144444134403024420111423244424030030003340213032121303213343020401304243330001314023030121034113334404440421242240113103203013341231330004332040302440011324004130324034323430143102401440130242321424020323 
c = 10013444120141130322433204124002242224332334011124210012440241402342100410331131441303242011002101323040403311120421304422222200324402244243322422444414043342130111111330022213203030324422101133032212042042243101434342203204121042113212104212423330331134311311114143200011240002111312122234340003403312040401043021433112031334324322123304112340014030132021432101130211241134422413442312013042141212003102211300321404043012124332013240431242

知识点:
中国剩余定理
解:
抄别人的

import gmpy2
from functools import reduce
from Crypto.Util.number import *

n1 = 331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101331214303223312402430402404413033243132101010422240133122211400434023222214231402403403200012221023341333340042343122302113410210110221233241303024431330001303404020104442443120130000334110042432010203401440404010003442001223042211442001413004 
c1 = 310020004234033304244200421414413320341301002123030311202340222410301423440312412440240244110200112141140201224032402232131204213012303204422003300004011434102141321223311243242010014140422411342304322201241112402132203101131221223004022003120002110230023341143201404311340311134230140231412201333333142402423134333211302102413111111424430032440123340034044314223400401224111323000242234420441240411021023100222003123214343030122032301042243

n2 = 302240000040421410144422133334143140011011044322223144412002220243001141141114123223331331304421113021231204322233120121444434210041232214144413244434424302311222143224402302432102242132244032010020113224011121043232143221203424243134044314022212024343100042342002432331144300214212414033414120004344211330224020301223033334324244031204240122301242232011303211220044222411134403012132420311110302442344021122101224411230002203344140143044114 
c2 = 112200203404013430330214124004404423210041321043000303233141423344144222343401042200334033203124030011440014210112103234440312134032123400444344144233020130110134042102220302002413321102022414130443041144240310121020100310104334204234412411424420321211112232031121330310333414423433343322024400121200333330432223421433344122023012440013041401423202210124024431040013414313121123433424113113414422043330422002314144111134142044333404112240344

n3 = 332200324410041111434222123043121331442103233332422341041340412034230003314420311333101344231212130200312041044324431141033004333110021013020140020011222012300020041342040004002220210223122111314112124333211132230332124022423141214031303144444134403024420111423244424030030003340213032121303213343020401304243330001314023030121034113334404440421242240113103203013341231330004332040302440011324004130324034323430143102401440130242321424020323 
c3 = 10013444120141130322433204124002242224332334011124210012440241402342100410331131441303242011002101323040403311120421304422222200324402244243322422444414043342130111111330022213203030324422101133032212042042243101434342203204121042113212104212423330331134311311114143200011240002111312122234340003403312040401043021433112031334324322123304112340014030132021432101130211241134422413442312013042141212003102211300321404043012124332013240431242

e = 3#猜的
n = [n1,n2,n3]
c = [c1,c2,c3]

for i in range(3):
    n[i] = int(str(n[i]),5)
    c[i] = int(str(c[i]),5)

def chinese_remainder(modulus,remainders):
    sum = 0
    prod = reduce(lambda a,b:a*b,modulus)
    for m_i,r_i in zip(modulus,remainders):
        p = prod // m_i
        sum += r_i * (inverse(p,m_i)*p)
    return sum % prod

pow_m_e = chinese_remainder(n,c)
m = gmpy2.iroot(pow_m_e, e)[0]
print(bytes.fromhex(hex(m)[2:]))

flag{D4mn_y0u_h4s74d_wh47_4_b100dy_b4s74rd!}

低解密指数攻击

e选取的较小而造成的缺陷,那么e选取的非常大是不是就很安全呢?
实际上也不是,当e很大时,就会造成d非常的小,也具有相当大的危险
针对d很小时的攻击方式,由Micheal j.Wiener于1989提出,所以也被称为Wiener’s attack,该方法基于连分数,该方法在github已有完整可用的代码,之后所有的低解密指数也是利用以上脚本进行的
rsa-wiener-attack

BUUCTF-rsa2

题目:

N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471
e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085

import hashlib
flag = "flag{" + hashlib.md5(hex(d)).hexdigest() + "}"

解:
用到RSAwienerHacker,好像需要在python2中运行,不然md5加密出现编码错误(我不会处理)

import RSAwienerHacker
import hashlib

N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471
e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085

d = RSAwienerHacker.hack_RSA(e,N)
flag = "flag{" + hashlib.md5(hex(d)).hexdigest() + "}"
print(flag)

flag{47bf28da384590448e0b0d23909a25a4}

BUUCTF-[INSHack2017]rsa16m

题目:
给出n,ce。其中n和c巨大。
思路:
由加密公式可以看出

\[c\;=\;m^e\;mod\;n \]

当c很大时,\(m^e<c\),此时对c开e次方就可能得到m。
解:

import gmpy2

path = r"D:\Downloads\tmp\rsa_16m"

data = open(path, 'r').read().split('\n')
c = int(data[1][4:], 16)
e = int(data[2][4:], 16)

m = gmpy2.iroot(c, e)[0]
print(bytes.fromhex(hex(m)[2:]))

flag{(I)NSA_W0uld_bE_pr0uD}

对e爆破

BUUCTF-[HDCTF2019]bbbbbbrsa

题目:

p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c = ==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM
from base64 import b64encode as b32encode
from gmpy2 import invert,gcd,iroot
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex
import random

flag = "******************************"

nbit = 128

p = getPrime(nbit)
q = getPrime(nbit)
n = p*q

print p
print n

phi = (p-1)*(q-1)

e = random.randint(50000,70000)

while True:
	if gcd(e,phi) == 1:
		break;
	else:
		e -= 1;

c = pow(int(b2a_hex(flag),16),e,n)

print b32encode(str(c))[::-1]

# 2373740699529364991763589324200093466206785561836101840381622237225512234632

思路:
看到c = '== + 数字和字母',可能是base32(实际是base64
解:

import gmpy2
import base64
from Crypto.Util.number import *

p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c = '==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM'
c = int(base64.b64decode(c[::-1]))
q = n//p
z = (p-1)*(q-1)

for e in range(50000,70000):
    if gmpy2.gcd(e,z) == 1:
        d = gmpy2.invert(e,z)
        m = gmpy2.powmod(c,d,n)
        flag = str(long_to_bytes(m))
        if 'flag' in flag:
            print(flag)

long_to_bytes()需要先pip install pycryptodome->from Crypto.Util.number import *
flag{rs4_1s_s1mpl3!#}

BUUCTF-[BJDCTF2020]RSA

题目:

from Crypto.Util.number import getPrime,bytes_to_long

flag=open("flag","rb").read()

p=getPrime(1024)
q=getPrime(1024)
assert(e<100000)
n=p*q
m=bytes_to_long(flag)
c=pow(m,e,n)
print c,n
print pow(294,e,n)

p=getPrime(1024)
n=p*q
m=bytes_to_long("BJD"*32)
c=pow(m,e,n)
print c,n

'''
output:
12641635617803746150332232646354596292707861480200207537199141183624438303757120570096741248020236666965755798009656547738616399025300123043766255518596149348930444599820675230046423373053051631932557230849083426859490183732303751744004874183062594856870318614289991675980063548316499486908923209627563871554875612702079100567018698992935818206109087568166097392314105717555482926141030505639571708876213167112187962584484065321545727594135175369233925922507794999607323536976824183162923385005669930403448853465141405846835919842908469787547341752365471892495204307644586161393228776042015534147913888338316244169120  13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
381631268825806469518166370387352035475775677163615730759454343913563615970881967332407709901235637718936184198930226303761876517101208677107311006065728014220477966000620964056616058676999878976943319063836649085085377577273214792371548775204594097887078898598463892440141577974544939268247818937936607013100808169758675042264568547764031628431414727922168580998494695800403043312406643527637667466318473669542326169218665366423043579003388486634167642663495896607282155808331902351188500197960905672207046579647052764579411814305689137519860880916467272056778641442758940135016400808740387144508156358067955215018
979153370552535153498477459720877329811204688208387543826122582132404214848454954722487086658061408795223805022202997613522014736983452121073860054851302343517756732701026667062765906277626879215457936330799698812755973057557620930172778859116538571207100424990838508255127616637334499680058645411786925302368790414768248611809358160197554369255458675450109457987698749584630551177577492043403656419968285163536823819817573531356497236154342689914525321673807925458651854768512396355389740863270148775362744448115581639629326362342160548500035000156097215446881251055505465713854173913142040976382500435185442521721  12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047
'''

解:

import gmpy2
from Crypto.Util.number import *

c = 12641635617803746150332232646354596292707861480200207537199141183624438303757120570096741248020236666965755798009656547738616399025300123043766255518596149348930444599820675230046423373053051631932557230849083426859490183732303751744004874183062594856870318614289991675980063548316499486908923209627563871554875612702079100567018698992935818206109087568166097392314105717555482926141030505639571708876213167112187962584484065321545727594135175369233925922507794999607323536976824183162923385005669930403448853465141405846835919842908469787547341752365471892495204307644586161393228776042015534147913888338316244169120
n = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037

c1 = 381631268825806469518166370387352035475775677163615730759454343913563615970881967332407709901235637718936184198930226303761876517101208677107311006065728014220477966000620964056616058676999878976943319063836649085085377577273214792371548775204594097887078898598463892440141577974544939268247818937936607013100808169758675042264568547764031628431414727922168580998494695800403043312406643527637667466318473669542326169218665366423043579003388486634167642663495896607282155808331902351188500197960905672207046579647052764579411814305689137519860880916467272056778641442758940135016400808740387144508156358067955215018
for e in range(100000):
    if c1 == gmpy2.powmod(294,e,n):
        print("e = {}".format(e))
        break

n1 = 12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047
p = gmpy2.gcd(n,n1)
q = n//p
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))

flag{p_is_common_divisor}

BUUCTF-[RoarCTF2019]RSA

题目:

A=(((y%x)**5)%(x%y))**2019+y**316+(y+1)/x
p=next_prime(z*x*y)
q=next_prime(z)
A =  2683349182678714524247469512793476009861014781004924905484127480308161377768192868061561886577048646432382128960881487463427414176114486885830693959404989743229103516924432512724195654425703453612710310587164417035878308390676612592848750287387318129424195208623440294647817367740878211949147526287091298307480502897462279102572556822231669438279317474828479089719046386411971105448723910594710418093977044179949800373224354729179833393219827789389078869290217569511230868967647963089430594258815146362187250855166897553056073744582946148472068334167445499314471518357535261186318756327890016183228412253724
n =  117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127
c =  41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128

解:

import gmpy2
import libnum

n =  117930806043507374325982291823027285148807239117987369609583515353889814856088099671454394340816761242974462268435911765045576377767711593100416932019831889059333166946263184861287975722954992219766493089630810876984781113645362450398009234556085330943125568377741065242183073882558834603430862598066786475299918395341014877416901185392905676043795425126968745185649565106322336954427505104906770493155723995382318346714944184577894150229037758434597242564815299174950147754426950251419204917376517360505024549691723683358170823416757973059354784142601436519500811159036795034676360028928301979780528294114933347127
c =  41971850275428383625653350824107291609587853887037624239544762751558838294718672159979929266922528917912189124713273673948051464226519605803745171340724343705832198554680196798623263806617998072496026019940476324971696928551159371970207365741517064295956376809297272541800647747885170905737868568000101029143923792003486793278197051326716680212726111099439262589341050943913401067673851885114314709706016622157285023272496793595281054074260451116213815934843317894898883215362289599366101018081513215120728297131352439066930452281829446586562062242527329672575620261776042653626411730955819001674118193293313612128
p = 842868045681390934539739959201847552284980179958879667933078453950968566151662147267006293571765463137270594151138695778986165111380428806545593588078365331313084230014618714412959584843421586674162688321942889369912392031882620994944241987153078156389470370195514285850736541078623854327959382156753458569
q = 139916095583110895133596833227506693679306709873174024876891023355860781981175916446323044732913066880786918629089023499311703408489151181886568535621008644997971982182426706592551291084007983387911006261442519635405457077292515085160744169867410973960652081452455371451222265819051559818441257438021073941183
z = (p-1)*(q-1)

for e in range(100000):
    if(gmpy2.gcd(e,z)==1):
        d=gmpy2.invert(e,z)
        m = gmpy2.powmod(c,d,n)
        flag = libnum.n2s(int(m))
        # 原题应该以CTF开头
        if('CTF' in str(flag)):
            print(flag)
            break

flag{wm-l1l1ll1l1l1l111ll}

公钥加签

BUUCTF-RSA

题目:
image
解:

  1. 利用公钥解析在线工具解析pub.key文件,得到n,e
    image
  2. 利用分解N的在线工具分解n,得到p,q
    image
  3. 写脚本,求z,d,key,并解密
import gmpy2
import rsa

n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
e = 65537
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
key = rsa.PrivateKey(n,e,d,p,q)

path = 'D:/Downloads/flag.txt'
with open(path,'rb') as f:
    f = f.read()
    print(rsa.decrypt(f,key))

flag{decrypt_256}

BUUCTF-[AFCTF2018]可怜的RSA

题目同上题
解:

  1. 由public.key可以解得en
from Crypto.PublicKey import RSA
 
path = r'D:/Downloads/public.key'
 
with open(path) as f:
    key = RSA.import_key(f.read())

print("e = {}".format(key.e))
print("n = {}".format(key.n))

# e = 65537
# n = 79832181757332818552764610761349592984614744432279135328398999801627880283610900361281249973175805069916210179560506497075132524902086881120372213626641879468491936860976686933630869673826972619938321951599146744807653301076026577949579618331502776303983485566046485431039541708467141408260220098592761245010678592347501894176269580510459729633673468068467144199744563731826362102608811033400887813754780282628099443490170016087838606998017490456601315802448567772411623826281747245660954245413781519794295336197555688543537992197142258053220453757666537840276416475602759374950715283890232230741542737319569819793988431443
  1. 利用分解N的在线工具分解n,得到p,q
import gmpy2
import rsa
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from base64 import b64decode

n = 79832181757332818552764610761349592984614744432279135328398999801627880283610900361281249973175805069916210179560506497075132524902086881120372213626641879468491936860976686933630869673826972619938321951599146744807653301076026577949579618331502776303983485566046485431039541708467141408260220098592761245010678592347501894176269580510459729633673468068467144199744563731826362102608811033400887813754780282628099443490170016087838606998017490456601315802448567772411623826281747245660954245413781519794295336197555688543537992197142258053220453757666537840276416475602759374950715283890232230741542737319569819793988431443
p = 3133337
q = n//p
e = 65537
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
key_info = RSA.construct((n, e, int(d), p, q))
key = RSA.importKey(key_info.exportKey())
key = PKCS1_OAEP.new(key)

path = r'D:/Downloads/flag.enc'
with open(path,'rb') as f:
    f = f.read()
    c = b64decode(f)
    print(key.decrypt(c))

flag{R54_|5_$0_B0rin9}

BUUCTF-[b01lers2020]safety_in_numbers

题目:
pubke.pem储存了n和e
flag.enc是加密结果
enc.py是加密脚本
enc.py:

import sys
import Crypto.PublicKey.RSA as RSA
def enc(msg, pubkey):
   (n,e) = pubkey
   m = int.from_bytes(msg, byteorder = 'little')
   c = pow(m, e, n)
   ctxt = (c).to_bytes(c.bit_length() // 8 + 1, byteorder = 'little')
   return ctxt
with open("pubkey.pem", "r") as f:
   ciph = RSA.importKey(f.read())     # chill out, Crypto.RSA takes its sweet time... (minutes)
pubkey = (ciph.n, ciph.e)
with open("flag.txt", "rb") as f:
   flag = f.read()
sys.stdout.buffer.write(enc(flag, pubkey))

pubkey.pem文件超级大。所以不是e很大就是n很大
读取时间很长,得到e=65537。所以是n很大,所以直接对c开e次方即可得到flag。
解:

import gmpy2
import libnum

e = 65537
with open('flag.enc','rb') as f:
    cipher = f.read()
c = int.from_bytes(cipher, byteorder='little')
m = gmpy2.iroot(c,e)[0]
print(libnum.n2s(m))
print(libnum.n2s(m)[::-1])

flag{!fUtuR3_pR00f}

杂项

BUUCTF-[ACTF新生赛2020]crypto-rsa0

伪加密+简单的RSA计算
解:

import gmpy2

e = 65537
p = 9018588066434206377240277162476739271386240173088676526295315163990968347022922841299128274551482926490908399237153883494964743436193853978459947060210411
q = 7547005673877738257835729760037765213340036696350766324229143613179932145122130685778504062410137043635958208805698698169847293520149572605026492751740223
c = 50996206925961019415256003394743594106061473865032792073035954925875056079762626648452348856255575840166640519334862690063949316515750256545937498213476286637455803452890781264446030732369871044870359838568618176586206041055000297981733272816089806014400846392307742065559331874972274844992047849472203390350

n = p*q
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
m = gmpy2.powmod(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

flag{n0w_y0u_see_RSA}

BUUCTF-[GWCTF 2019]BabyRSA

题目:

import hashlib
import sympy
from Crypto.Util.number import *

flag = 'GWHT{******}'
secret = '******'

assert(len(flag) == 38)

half = len(flag) / 2

flag1 = flag[:half]
flag2 = flag[half:]

secret_num = getPrime(1024) * bytes_to_long(secret)

p = sympy.nextprime(secret_num)
q = sympy.nextprime(p)

N = p * q

e = 0x10001

F1 = bytes_to_long(flag1)
F2 = bytes_to_long(flag2)

c1 = F1 + F2
c2 = pow(F1, 3) + pow(F2, 3)
assert(c2 < N)

m1 = pow(c1, e, N)
m2 = pow(c2, e, N)

output = open('secret', 'w')
output.write('N=' + str(N) + '\n')
output.write('m1=' + str(m1) + '\n')
output.write('m2=' + str(m2) + '\n')
output.close()
N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546

思路:

解:

import gmpy2
import sympy.crypto.crypto
import binascii

n = 636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1 = 90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2 = 487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
e = 0x10001

x = gmpy2.iroot(n,2)[0]
p = sympy.crypto.crypto.nextprime(x)
q = n//p
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
c1 = gmpy2.powmod(m1,d,n)
c2 = gmpy2.powmod(m2,d,n)
n = c1
m = c2
f1 = gmpy2.iroot((((m//n)-n*n)//3)+(n*n)//4,2)[0]+n//2
f2 = n - f1
print(binascii.unhexlify(hex(f1)[2:])+binascii.unhexlify(hex(f2)[2:]))

flag{f709e0e2cfe7e530ca8972959a1033b2}

BUUCTF-[ACTF新生赛2020]crypto-rsa3

题目:
ras3.py

from flag import FLAG
from Cryptodome.Util.number import *
import gmpy2
import random

e=65537
p = getPrime(512)
q = int(gmpy2.next_prime(p))
n = p*q
m = bytes_to_long(FLAG)
c = pow(m,e,n)
print(n)
print(c)

output.txt

177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683
1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049

解:
已知n、c、e
并且知道p、q相似,可以对n开方

import gmpy2
import sympy

n = 177606504836499246970959030226871608885969321778211051080524634084516973331441644993898029573612290095853069264036530459253652875586267946877831055147546910227100566496658148381834683037366134553848011903251252726474047661274223137727688689535823533046778793131902143444408735610821167838717488859902242863683
c = 1457390378511382354771000540945361168984775052693073641682375071407490851289703070905749525830483035988737117653971428424612332020925926617395558868160380601912498299922825914229510166957910451841730028919883807634489834128830801407228447221775264711349928156290102782374379406719292116047581560530382210049
e = 65537

p = sympy.nextprime(gmpy2.iroot(n,2)[0])
q = n // p
z = (p-1)*(q-1)
d = gmpy2.invert(e,z)
m = gmpy2.powmod(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

flag{p_and_q_should_not_be_so_close_in_value}

BUUCTF-[RoarCTF2019]babyRSA

威尔逊定理
题目:

import sympy
import random

def myGetPrime():
    A= getPrime(513)
    print(A)
    B=A-random.randint(1e3,1e5)
    print(B)
    return sympy.nextPrime((B!)%A)
p=myGetPrime()
#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596

q=myGetPrime()
#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026

r=myGetPrime()

n=p*q*r
#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
c=pow(flag,e,n)
#e=0x1001
#c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
#so,what is the flag?

解:

import gmpy2
from Crypto.Util.number import *

def wilison(b,a):
    p=1
    b=b+1
    while b<a:
        p *= b
        p = p % a
        b = b + 1
    return p

c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596
A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026
e=0x1001

invert1 = gmpy2.invert(wilison(B1,A1),A1)
invert2 = gmpy2.invert(wilison(B2,A2),A2)

q = gmpy2.next_prime((invert1*(-1))%A1)
p = gmpy2.next_prime((invert2*(-1))%A2)
r = n//p//q
z = (p-1)*(q-1)*(r-1)
d = gmpy2.invert(e,int(z))
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))

flag{wm-CongrAtu1ation4-1t4-ju4t-A-bAby-R4A}

BUUCTF-[网鼎杯 2020 青龙组]you_raise_me_up

题目:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import random

n = 2 ** 512
m = random.randint(2, n-1) | 1
c = pow(m, bytes_to_long(flag), n)
print 'm = ' + str(m)
print 'c = ' + str(c)

# m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
# c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499

解:

import libnum
import sympy

c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
n = 2 ** 512

flag = sympy.discrete_log(n,c,m) # pow的逆运算
print(libnum.n2s(int(flag)))

flag{5f95ca93-1594-762d-ed0b-a9139692cb4a}

BUUCTF-RSA & what

共模攻击+base64隐写
题目:

from Crypto.Util.number import bytes_to_long, getPrime
from random import randint
from gmpy2 import powmod

p = getPrime(2048)
q = getPrime(2048)
N = p*q
Phi = (p-1)*(q-1)
def get_enc_key(N,Phi):
    e = getPrime(N)
    if Phi % e == 0:
        return get_enc_key(N, Phi)
    else:
        return e
e1 = get_enc_key(randint(10, 12), Phi)
e2 = get_enc_key(randint(10, 12), Phi)

fr = open(r"./base64", "rb")#flag is in this file
f1 = open(r"./HUB1", "wb")
f2 = open(r"./HUB2", "wb")
base64 = fr.read(255)
f1.write("%d\n%d\n" % (N, e1))
f2.write("%d\n%d\n" % (N, e2))
while len(base64)>0:
    pt = bytes_to_long(base64)
    ct1 = powmod(pt, e1, N)
    ct2 = powmod(pt, e2, N)
    f1.write("\n%d" % ct1)
    f2.write("\n%d" % ct2)
    base64 = fr.read(255)
fr.close()
f1.close()
f2.close()

思路:
解:

import gmpy2
import base64

path1 = r"D:\Downloads\rsawhat\HUB1"
path2 = r"D:\Downloads\rsawhat\HUB2"

# 补全base64的'='
def decode_base64(data):
    missing_padding = 4 - len(data) % 4
    if missing_padding:
        data += '=' * missing_padding
    return str(base64.b64decode(data), encoding='utf-8', errors='ignore')

# base64隐写
def b64_stego_decode(base64_):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    data=''
    Bytes=""
    num=0
    for i in range(len(base64_)):
        if base64_[i] == '=':
            data = "00"
            num -= 2
        else:
            data = bin(base64chars.find(base64_[i]))[2:]
            Bytes += data.zfill(6)
    return Bytes[num:]

with open(path1, 'r') as f:
    data = f.readlines()
    data = [line.strip("\n") for line in data]
    data1 = list(filter(None, data))
    # print(data1)

with open(path2, 'r') as f:
    data = f.readlines()
    data = [line.strip("\n") for line in data]
    data2 = list(filter(None, data))
    # print(data2)

n = int(data1[0])
e1 = data1[1]
e2 = data2[1]
r , s1 , s2 = gmpy2.gcdext(int(e1),int(e2))

res = ''
res1 = ''
for i in range(2,len(data1)):
    m = (gmpy2.powmod(int(data1[i]),s1,n)*gmpy2.powmod(int(data2[i]),s2,n)) % n
    res += bytes.fromhex(hex(m)[2:]).decode('utf-8')
    res1 += bytes.fromhex(hex(m)[2:]).decode('utf-8').replace('\n', '').replace('\r', '')
    # print(res)
    # print(res.replace('\n', '').replace('\r', ''))

res1 += "=="
x = 0
ress = []
for i in range(len(res1)):
    if res1[i] == '=' and res1[i-1] == '=':
        ress.append(decode_base64(res1[x:i]))
        # print(decode_base64(res1[x:i]))
        x = i + 1
    if res1[i] == '=' and res1[i-1] != '=':
        ress.append(decode_base64(res1[x:i]))
        # print(decode_base64(res1[x:i]))
        x = i + 1

ress = list(filter(None, ress))
# print(" ".join(ress))

res = res.splitlines()
flag = ''
bin_str = ''
for line in res:
    # base64 = str(line,"utf-8").strip("\n")
    if(not line.count('=')):
        continue
    bin_str += b64_stego_decode(line)
for j in range(0,len(bin_str),8):
    flag += chr(int(bin_str[j:j+8],2))
print("flag{{{}}}".format(flag.strip(b'\x00'.decode())))

flag{7c86d8f7d6de33a87f7f9d6b005ce640}

BUUCTF-[MRCTF2020]babyRSA

题目:

import sympy
import random
from gmpy2 import gcd, invert
from Crypto.Util.number import getPrime, isPrime, getRandomNBitInteger, bytes_to_long, long_to_bytes
from z3 import *
flag = b"MRCTF{xxxx}"
base = 65537


def GCD(A):
    B = 1
    for i in range(1, len(A)):
        B = gcd(A[i-1], A[i])
    return B


def gen_p():
    P = [0 for i in range(17)]
    P[0] = getPrime(128)
    for i in range(1, 17):
        P[i] = sympy.nextprime(P[i-1])
    print("P_p :", P[9])
    n = 1
    for i in range(17):
        n *= P[i]
    p = getPrime(1024)
    factor = pow(p, base, n)
    print("P_factor :", factor)
    return sympy.nextprime(p)


def gen_q():
    sub_Q = getPrime(1024)
    Q_1 = getPrime(1024)
    Q_2 = getPrime(1024)
    Q = sub_Q ** Q_2 % Q_1
    print("Q_1: ", Q_1)
    print("Q_2: ", Q_2)
    print("sub_Q: ", sub_Q)
    return sympy.nextprime(Q)


if __name__ == "__main__":
    _E = base
    _P = gen_p()
    _Q = gen_q()
    assert (gcd(_E, (_P - 1) * (_Q - 1)) == 1)
    _M = bytes_to_long(flag)
    _C = pow(_M, _E, _P * _Q)
    print("Ciphertext = ", _C)
'''
P_p : 206027926847308612719677572554991143421
P_factor : 213671742765908980787116579976289600595864704574134469173111790965233629909513884704158446946409910475727584342641848597858942209151114627306286393390259700239698869487469080881267182803062488043469138252786381822646126962323295676431679988602406971858136496624861228526070581338082202663895710929460596143281673761666804565161435963957655012011051936180536581488499059517946308650135300428672486819645279969693519039407892941672784362868653243632727928279698588177694171797254644864554162848696210763681197279758130811723700154618280764123396312330032986093579531909363210692564988076206283296967165522152288770019720928264542910922693728918198338839
Q_1:  103766439849465588084625049495793857634556517064563488433148224524638105971161051763127718438062862548184814747601299494052813662851459740127499557785398714481909461631996020048315790167967699932967974484481209879664173009585231469785141628982021847883945871201430155071257803163523612863113967495969578605521
Q_2:  151010734276916939790591461278981486442548035032350797306496105136358723586953123484087860176438629843688462671681777513652947555325607414858514566053513243083627810686084890261120641161987614435114887565491866120507844566210561620503961205851409386041194326728437073995372322433035153519757017396063066469743
sub_Q:  168992529793593315757895995101430241994953638330919314800130536809801824971112039572562389449584350643924391984800978193707795909956472992631004290479273525116959461856227262232600089176950810729475058260332177626961286009876630340945093629959302803189668904123890991069113826241497783666995751391361028949651
Ciphertext =  1709187240516367141460862187749451047644094885791761673574674330840842792189795049968394122216854491757922647656430908587059997070488674220330847871811836724541907666983042376216411561826640060734307013458794925025684062804589439843027290282034999617915124231838524593607080377300985152179828199569474241678651559771763395596697140206072537688129790126472053987391538280007082203006348029125729650207661362371936196789562658458778312533505938858959644541233578654340925901963957980047639114170033936570060250438906130591377904182111622236567507022711176457301476543461600524993045300728432815672077399879668276471832
'''

提示:

  1. a ** b % c等价于RSA加解密公式,需要用pow计算。
  2. n由若干个质数相乘得到,z则可以由这些质数分别-1再相乘得到。

解:

import gmpy2
import sympy

P_p = 206027926847308612719677572554991143421
P_factor = 213671742765908980787116579976289600595864704574134469173111790965233629909513884704158446946409910475727584342641848597858942209151114627306286393390259700239698869487469080881267182803062488043469138252786381822646126962323295676431679988602406971858136496624861228526070581338082202663895710929460596143281673761666804565161435963957655012011051936180536581488499059517946308650135300428672486819645279969693519039407892941672784362868653243632727928279698588177694171797254644864554162848696210763681197279758130811723700154618280764123396312330032986093579531909363210692564988076206283296967165522152288770019720928264542910922693728918198338839
Q_1 = 103766439849465588084625049495793857634556517064563488433148224524638105971161051763127718438062862548184814747601299494052813662851459740127499557785398714481909461631996020048315790167967699932967974484481209879664173009585231469785141628982021847883945871201430155071257803163523612863113967495969578605521
Q_2 = 151010734276916939790591461278981486442548035032350797306496105136358723586953123484087860176438629843688462671681777513652947555325607414858514566053513243083627810686084890261120641161987614435114887565491866120507844566210561620503961205851409386041194326728437073995372322433035153519757017396063066469743
sub_Q = 168992529793593315757895995101430241994953638330919314800130536809801824971112039572562389449584350643924391984800978193707795909956472992631004290479273525116959461856227262232600089176950810729475058260332177626961286009876630340945093629959302803189668904123890991069113826241497783666995751391361028949651
Ciphertext = 1709187240516367141460862187749451047644094885791761673574674330840842792189795049968394122216854491757922647656430908587059997070488674220330847871811836724541907666983042376216411561826640060734307013458794925025684062804589439843027290282034999617915124231838524593607080377300985152179828199569474241678651559771763395596697140206072537688129790126472053987391538280007082203006348029125729650207661362371936196789562658458778312533505938858959644541233578654340925901963957980047639114170033936570060250438906130591377904182111622236567507022711176457301476543461600524993045300728432815672077399879668276471832
e = 65537

def solve_p():
    P = [0 for i in range(17)]
    P[9] = P_p
    n = 1
    z = 1
    for i in range(8, -1, -1):
        P[i] = sympy.prevprime(P[i+1])
    for i in range(10, 17):
        P[i] = sympy.nextprime(P[i-1])
    for i in range(17):
        n *= P[i]
        z *= (P[i]-1)
    tem_d = gmpy2.invert(e,z)
    p = gmpy2.powmod(P_factor,tem_d,n)
    return sympy.nextprime(p)

def solve_q():
    q = gmpy2.powmod(sub_Q, Q_2, Q_1)
    return sympy.nextprime(q)

if __name__ == "__main__":
    p = solve_p()
    q = solve_q()
    n = p * q
    z = (p-1)*(q-1)
    d = gmpy2.invert(e,z)
    m = gmpy2.powmod(Ciphertext,d,n)
    print(bytes.fromhex(hex(m)[2:]))

flag{sti11_@_b@by_qu3st10n}

BUUCTF-[INSHack2019]Yet Another RSA Challenge - Part 1

题目:

import subprocess
p = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
q = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
flag = int('INSA{REDACTED}'.encode('hex'), 16)

N = int(p,16) * int(q,16)
print N
print '0x'+p.replace('9F','FC')
print pow(flag,65537,N)

思路:
输出的p是被替换过的,但是不能确保原来的p中没有FC。所以需要爆破,爆破成功的条件就是n能被p整除。
可能非唯一解。
解:

import gmpy2
import itertools

n = 719579745653303119025873098043848913976880838286635817351790189702008424828505522253331968992725441130409959387942238566082746772468987336980704680915524591881919460709921709513741059003955050088052599067720107149755856317364317707629467090624585752920523062378696431510814381603360130752588995217840721808871896469275562085215852034302374902524921137398710508865248881286824902780186249148613287250056380811479959269915786545911048030947364841177976623684660771594747297272818410589981294227084173316280447729440036251406684111603371364957690353449585185893322538541593242187738587675489180722498945337715511212885934126635221601469699184812336984707723198731876940991485904637481371763302337637617744175461566445514603405016576604569057507997291470369704260553992902776099599438704680775883984720946337235834374667842758010444010254965664863296455406931885650448386682827401907759661117637294838753325610213809162253020362015045242003388829769019579522792182295457962911430276020610658073659629786668639126004851910536565721128484604554703970965744790413684836096724064390486888113608024265771815004188203124405817878645103282802994701531113849607969243815078720289912255827700390198089699808626116357304202660642601149742427766381
false_p = "0xDCC5A0BD3A1FC0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331AFCFD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14FCD2739D76E69283E57DDB11FC531B4611EE3"
c = 596380963583874022971492302071822444225514552231574984926542429117396590795270181084030717066220888052607057994262255729890598322976783889090993129161030148064314476199052180347747135088933481343974996843632511300255010825580875930722684714290535684951679115573751200980708359500292172387447570080875531002842462002727646367063816531958020271149645805755077133231395881833164790825731218786554806777097126212126561056170733032553159740167058242065879953688453169613384659653035659118823444582576657499974059388261153064772228570460351169216103620379299362366574826080703907036316546232196313193923841110510170689800892941998845140534954264505413254429240789223724066502818922164419890197058252325607667959185100118251170368909192832882776642565026481260424714348087206462283972676596101498123547647078981435969530082351104111747783346230914935599764345176602456069568419879060577771404946743580809330315332836749661503035076868102720709045692483171306425207758972682717326821412843569770615848397477633761506670219845039890098105484693890695897858251238713238301401843678654564558196040100908796513657968507381392735855990706254646471937809011610992016368630851454275478216664521360246605400986428230407975530880206404171034278692756
e = 65537

# 方法1-大N分解
# 方法2-恢复'9F'
tmp = false_p.split("FC")
a = ['9F', 'FC']
b = 4
sets = [''.join(x) for x in itertools.product(*[a] *b)]
for i in range(len(a)**b-1):
    solve_p = tmp[0] + sets[i][0:2] + tmp[1] + sets[i][2:4] + tmp[2] + sets[i][4:6] + tmp[3] + sets[i][6:8] + tmp[4]
    solve_p = int(solve_p, 16)
    if (n % solve_p == 0):
        p = solve_p
        break

q = n//p
z = (p-1)*(q-1)
d = gmpy2.invert(e, z)
m = gmpy2.powmod(c, d, n)
print(bytes.fromhex(hex(m)[2:]))

flag{I_w1ll_us3_OTp_n3xT_T1M3}

BUUCTF-[INSHack2019]Yet Another RSA Challenge - Part 1

题目:
题目经过字母替换了,利用进阶凯撒破解可以得到题目源码。

from gmpy2 import is_prime
from os import urandom 
import base64

def bytes_to_num(b):
	return int(b.encode('hex'), 16) 

def num_to_bytes(n): 
	b = hex(n)[2:-1] 
	b = '0' + b if len(b)%2 == 1 else b 
	return b.decode('hex') 
	
def get_a_prime(l): 
	random_seed = urandom(l) 
	
	num = bytes_to_num(random_seed) 
	
	while Srue: 
		if is_prime(num): 
			break 
		num+=1 
	return num 

def encrypt(s, e, n): 
	p = bytes_to_num(s) 
	p = pow(p, e, n) 
	return num_to_bytes(p).encode('hex') 

def separate(n): 
	p = n % 4 
	t = (p*p) % 4 
	return t == 1 
	
f = open('flag.txt', 'r')
flag = f.read() 

msg1 = "" 
msg2 = "" 
for i in range(len(flag)): 
	if separate(i): 
		msg2 += flag[i] 
	else: 
		msg1 += flag[i] 
		
p1 = get_a_prime(128) 
p2 = get_a_prime(128) 
p3 = get_a_prime(128) 
n1 = p1*p2 
n2 = p1*p3 
e = 0x1001 
c1 = encrypt(msg1, e, n1) 
c2 = encrypt(msg2, e, n2) 
print(c1) print(c2) 
e1 = 0x1001 
e2 = 0x101 
p4 = get_a_prime(128) 
p5 = get_a_prime(128) 
n3 = p4*p5 
c1 = num_to_bytes(pow(n1, e1, n3)).encode('hex') 
c2 = num_to_bytes(pow(n1, e2, n3)).encode('hex') 
print(c1) 
print(c2) 

print(base64.b64encode(num_to_bytes(n2))) 
print(base64.b64encode(num_to_bytes(n3)))

思路:
共模攻击+欧几里得算法
解:

from Crypto.Util.number import *
from gmpy2 import *
import base64

n1_c1 = int('0x2639c28e3609a4a8c953cca9c326e8e062756305ae8aee6efcd346458aade3ee8c2106ab9dfe5f470804f366af738aa493fd2dc26cb249a922e121287f3eddec0ed8dea89747dc57aed7cd2089d75c23a69bf601f490a64f73f6a583081ae3a7ed52238c13a95d3322065adba9053ee5b12f1de1873dbad9fbf4a50a2f58088df0fddfe2ed8ca1118c81268c8c0fd5572494276f4e48b5eb424f116e6f5e9d66da1b6b3a8f102539b690c1636e82906a46f3c5434d5b04ed7938861f8d453908970eccef07bf13f723d6fdd26a61be8b9462d0ddfbedc91886df194ea022e56c1780aa6c76b9f1c7d5ea743dc75cec3c805324e90ea577fa396a1effdafa3090',16)
n1_c2 = int('0x42ff1157363d9cd10da64eb4382b6457ebb740dbef40ade9b24a174d0145adaa0115d86aa2fc2a41257f2b62486eaebb655925dac78dd8d13ab405aef5b8b8f9830094c712193500db49fb801e1368c73f88f6d8533c99c8e7259f8b9d1c926c47215ed327114f235ba8c873af7a0052aa2d32c52880db55c5615e5a1793b690c37efdd5e503f717bb8de716303e4d6c4116f62d81be852c5d36ef282a958d8c82cf3b458dcc8191dcc7b490f227d1562b1d57fbcf7bf4b78a5d90cd385fd79c8ca4688e7d62b3204aeaf9692ba4d4e44875eaa63642775846434f9ce51d138ca702d907849823b1e86896e4ea6223f93fae68b026cfe5fa5a665569a9e3948a',16)
n2 = 'PVNHb2BfGAnmxLrbKhgsYXRwWIL9eOj6K0s3I0slKHCTXTAUtZh3T0r+RoSlhpO3+77AY8P7WETYz2Jzuv5FV/mMODoFrM5fMyQsNt90VynR6J3Jv+fnPJPsm2hJ1Fqt7EKaVRwCbt6a4BdcRoHJsYN/+eh7k/X+FL5XM7viyvQxyFawQrhSV79FIoX6xfjtGW+uAeVF7DScRcl49dlwODhFD7SeLqzoYDJPIQS+VSb3YtvrDgdV+EhuS1bfWvkkXRijlJEpLrgWYmMdfsYX8u/+Ylf5xcBGn3hv1YhQrBCg77AHuUF2w/gJ/ADHFiMcH3ux3nqOsuwnbGSr7jA6Cw=='
n3 = 'TmNVbWUhCXR1od3gBpM+HGMKK/4ErfIKITxomQ/QmNCZlzmmsNyPXQBiMEeUB8udO7lWjQTYGjD6k21xjThHTNDG4z6C2cNNPz73VIaNTGz0hrh6CmqDowFbyrk+rv53QSkVKPa8EZnFKwGz9B3zXimm1D+01cov7V/ZDfrHrEjsDkgK4ZlrQxPpZAPl+yqGlRK8soBKhY/PF3/GjbquRYeYKbagpUmWOhLnF4/+DP33ve/EpaSAPirZXzf8hyatL4/5tAZ0uNq9W6T4GoMG+N7aS2GeyUA2sLJMHymW4cFK5l5kUvjslRdXOHTmz5eHxqIV6TmSBQRgovUijlNamQ=='
c1 = 0x1240198b148089290e375b999569f0d53c32d356b2e95f5acee070f016b3bef243d0b5e46d9ad7aa7dfe2f21bda920d0ac7ce7b1e48f22b2de410c6f391ce7c4347c65ffc9704ecb3068005e9f35cbbb7b27e0f7a18f4f42ae572d77aaa3ee189418d6a07bab7d93beaa365c98349d8599eb68d21313795f380f05f5b3dfdc6272635ede1f83d308c0fdb2baf444b9ee138132d0d532c3c7e60efb25b9bf9cb62dba9833aa3706344229bd6045f0877661a073b6deef2763452d0ad7ab3404ba494b93fd6dfdf4c28e4fe83a72884a99ddf15ca030ace978f2da87b79b4f504f1d15b5b96c654f6cd5179b72ed5f84d3a16a8f0d5bf6774e7fd98d27bf3c9839
c2 = 0x129d5d4ab3f9e8017d4e6761702467bbeb1b884b6c4f8ff397d078a8c41186a3d52977fa2307d5b6a0ad01fedfc3ba7b70f776ba3790a43444fb954e5afd64b1a3abeb6507cf70a5eb44678a886adf81cb4848a35afb4db7cd7818f566c7e6e2911f5ababdbdd2d4ff9825827e58d48d5466e021a64599b3e867840c07e29582961f81643df07f678a61a9f9027ebd34094e272dfbdc4619fa0ac60f0189af785df77e7ec784e086cf692a7bf7113a7fb8446a65efa8b431c6f72c14bcfa49c9b491fb1d87f2570059e0f13166a85bb555b40549f45f04bc5dbd09d8b858a5382be6497d88197ffb86381085756365bd757ec3cdfa8a77ba1728ec2de596c5ab
n2 = bytes_to_long(base64.b64decode(n2))
n3 = bytes_to_long(base64.b64decode(n3))
e = 0x1001
e1 = 0x1001 
e2 = 0x101 

r , s1 , s2 = gmpy2.gcdext(e1,e2)
n1 = (gmpy2.powmod(n1_c1,s1,n3)*gmpy2.powmod(n1_c2,s2,n3)) % n3

p1 = gmpy2.gcd(n1,n2)
p2 = n1//p1
p3 = n2//p1
z1 = (p1-1)*(p2-1)
z2 = (p1-1)*(p3-1)
d1 = gmpy2.invert(e,z1)
d2 = gmpy2.invert(e,z2)
msg1 = gmpy2.powmod(c1,d1,n1)
msg2 = gmpy2.powmod(c2,d2,n2)
# print(bytes.fromhex(hex(msg1)[2:]))
# print(bytes.fromhex(hex(msg2)[2:]))

msg1=(long_to_bytes(msg1)).decode()
msg2=(long_to_bytes(msg2)).decode()

def separate(n): 
    p = n % 4 
    t = (p*p) % 4 
    return t == 1

flag=''
m1=0
m2=0
for i in range(0,len(msg1)+len(msg2)):
    if separate(i):
        flag+=msg2[m1]
        m1+=1
    else:
        flag+=msg1[m2]
        m2+=1
print(flag)

flag{CRYPT0_I5_50_Interestingvim rsa.py}




参考链接:
http://happi0.gitee.io/happi0/2020/10/25/RSA入门到入坟/#toc-heading-13
https://blog.csdn.net/weixin_43790779/article/details/108473984
https://blog.csdn.net/mikecoke/category_9972314.html
https://blog.csdn.net/MikeCoke/article/details/105967809
https://blog.csdn.net/qq_32350719/article/details/102719279
https://www.cnblogs.com/vict0r/p/13474058.html
https://www.jianshu.com/p/f361c9b9bfe8
https://blog.csdn.net/m0_57291352/article/details/118499479
https://www.cnblogs.com/jane315/p/13805724.html
https://blog.csdn.net/qq_46230755/article/details/111290544
https://blog.csdn.net/weixin_44110537/article/details/107385301
https://blog.csdn.net/weixin_39934520/article/details/122014418
https://www.cnblogs.com/Mr-small/p/13631779.html
https://blog.csdn.net/zippo1234/article/details/109270719
https://www.jianshu.com/p/86146795482a
https://blog.csdn.net/zippo1234/article/details/109287550


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM