RSA相關知識點與攻擊方法


相關工具/方法

大數分解

大數分解網頁

http://www.factordb.com/index.php

yafu

  1. 運行yafu-x64.exe,在窗口中輸入factor(n),n即為待分解的大數。
  2. 在factor.log中找到分解結果。

利用z3解方程

可以加快解題速度,此處以一個簡單的例子展示如何用z3解方程(首先需要安裝z3和z3-solver)。
\(\begin{cases}\ x1+x2=3\\\ x1-x2=-1\end{cases}\)

from z3 import *

x1 = Int('x1')
x2 = Int('x2')
s = Solver()
s.add(x1 + x2 == 3)
s.add(x1 - x2 == -1)
if s.check()==sat:
    print(s.model())

如例題[GWCTF 2019]BabyRSA

已知p,q,e求d

方法一:

p=473398607161
q=4511491
e=17
n = (p-1) * (q-1)

def extendedEuclid(a, b):
    if b == 0:
        return 1, 0
    else:
        x, y= extendedEuclid(b, a % b)
        x, y = y, (x - (a // b) * y)
        return x, y
d = extendedEuclid(e,n)[0]
print(d)

方法二(常用,gmpy2庫):

# 已知e,p,q
import gmpy2
phin = (p-1) * (q-1)
d = gmpy2.invert(e,phin)

方法三(sage):

phin = (p-1) * (q-1)
d = inverse_mod(e,phin)

已知n,dp,e求d

相關例題如:Buuoj RSA2

  1. 要先根據e,dp求p。首先
      \(dp\ =\ d\ mod\ (p-1)\)
      \(ed\ \equiv\ 1\ mod\ \phi(n)\)
    \(\phi(n)\ =\ (p-1)(q-1)\),所以有
      \(ed\ =\ 1+x(p-1)(q-1)\)
      \(edp\ mod\ (p-1)\ \equiv\ ed\ mod\ (p-1)\)
    進而:
      \(edp\ =\ ed+y(p-1)\)
      \(edp\ =\ 1+x(p-1)(q-1)+y(p-1)\)
    因此可整理為:
      \(edp\ =\ 1+y(p-1)\)
    又有\(dp\ \lt\ p-1\),所以\(e\ \gt\ y\)。從1到e遍歷即可求得正確的y,進而得到正確的p值。得到p后可有已知的n求得q,進而回到已知\(e\)\(\phi(n)\)求解\(d\)的問題。得到代碼如下,注意求p時是整型除法,否則會在n%p時報溢出錯誤:
for y in range(1,e):
    if (e*dp - 1)%y == 0:
        p = (e*dp - 1)//y + 1
        if n%p == 0:
            print(p)
            break

小指數明文爆破

相關例題,Buuoj Dangerous RSA

  1. 題目已知條件有n,e,c其中e是非常小的值,比如3。RSA的加密過程為\(c=m^e\ mod\ n\)
    如果m很小,n很大,也即可能是以下情況\(^{[2]}\)
      \(m^e\ \lt\ n\)
    此時,\(c=m^e\),開e次根即可得到m。
    如果,\(m^e \gt\ n\)但是並未超過n太多,又由於對c我們可能有\(m^e=c+kn\),所以可以得到以下的表達式:
      \(m=\sqrt[e]{c+kn}\)
    這樣我們可以通過爆破k的大小來求解明文了。
  2. 基本代碼如下:
# 已知n,e,c
import gmpy2
from Crypto.Util.number import long_to_bytes
k = 0
while 1:
    if gmpy2.iroot(c+k*n,e)[1]==1:
        print(long_to_bytes(gmpy2.iroot(c+k*n,e)[0]))
        break
    k += 1

iroot(c+k*n,e)函數就是在計算\(\sqrt[e]{c+kn}\),其返回結果第一個元素為計算結果,第二個元素是表示結果是否精確的布爾值

分數,求導

相關例題:[BJDCTF2020]easyrsa

分數

# Fraction(8, 6) will produce a rational number equivalent to 4/3, Both arguments must be Rational. The numerator defaults to 0 and the denominator defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
from fractions import Fraction
x = Fraction(8,6)

求導

http://liao.cpython.org/scipy17/
如對\(arctan(p)\)求導(p為變量)

from sympy import Derivative
x = Derivative(arctan(p),p)

已知e,n且e很大時求d -> RSA Wiener Attack 維納攻擊

參考:https://github.com/pablocelayes/rsa-wiener-attack
求d的方法:

from RSAwienerHacker import hack_RSA
d = hack_RSA(e,n)

相關例題Buuoj rsa2

openssl

  1. 首先需要下載安裝openssl,下載地址
  2. 將其bin目錄添加到系統變量path中
  3. 基本用法參考https://www.cnblogs.com/wyzhou/p/9738964.html
  4. 如利用openssl從文件獲取公鑰信息(不輸出文件):openssl rsa -pubin -in key.pub -text -noout

利用Crypto.PublicKey的RSA模塊從文件中獲取公鑰信息n,e

這個文件可能是二進制文件,key.pub,pub.key等形式

from Crypto.PublicKey import RSA
f = open("key.pub","rb").read()
pub = RSA.importKey(f)
print(pub.n,pub.e)

相關例題:Buuoj RSA, 攻防世界 cr4-poor-rsa

已知e,d的值和p,q的位數,求p,q的值

先驗知識:
  \(n=pq\)
  \(\phi(n)=(p-1)(q-1)\)
  \(ed\equiv1\ mod\ \phi(n)\)
所以,大概有\(ed-1=x*\phi(n)\)
如果我們已知p,q的位數,那就大概知道n的位數,\(\phi(n)\)的位數與n差別不大。同時\(ed-1\)的位數可以通過其值得到范圍,因此我們可以通過\(\frac{(ed-1)的位數}{\phi(n)的位數}\)大致確定x的位數,隨即可以在此范圍遍歷得到素數p,q的值。
相關例題:[NCTF2019]babyRSA

已知多組n,c的值

中國剩余定理

參考代碼

遍歷n,看有無非1的公因數,其值即為p或q的值

RsaCtfTool

源代碼

  1. 安裝過程中注意mpfr和mpc都應從官網確認最新版本后再下載對應版本並安裝。
  2. 使用方法:``

已知n的值,且p,q大小相近,如何求出p和q

  1. 先對n求平方根,得到一個和p值相近的值,再求其臨近的素數,即為p值
  2. q = n // p
near_p = isqrt(n)
p = next_prime(near_p)
q = n // p

已知dp,dq,p,q,c求明文

參考

import gmpy2
import binascii


def decrypt(dp, dq, p, q, c):
    InvQ = gmpy2.invert(q, p)
    mp = pow(c, dp, p)
    mq = pow(c, dq, q)
    m = (((mp-mq)*InvQ) % p)*q+mq
    print(binascii.unhexlify(hex(m)[2:]))

例題

Buuoj RSA

解法一

  1. 給了flag.enc和pub.key文件,其中pub.key文件存放了公鑰信息,這是個ASCII文本文件可直接用記事本打開。得到以下信息:

-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+
/AvKr1rzQczdAgMBAAE=
-----END PUBLIC KEY-----

  1. 借助RSA密鑰解析網站解析密鑰指數和模數信息,得以下結果:

key長度:256
模數:C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD
指數:65537

  1. 用Python得到n的十進制形式
n = '0xC0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD'
n = int(n,16)
  1. 得到n=86934482296048119190666062003494800588905656017203025617216654058378322103517,放到大數分解網站分解。得到:

p=285960468890451637935629440372639283459
q=304008741604601924494328155975272418463

  1. 利用gmpy2庫求解d,由以上已得數據有以下代碼d = gmpy2.invert(e,(p-1)*(q-1)),得到:

d=81176168860169991027846870170527607562179635470395365333547868786951080991441

注意這個invert函數的用法:

invert(x, m) Return y such that x*y == 1 (mod m).

  1. 最后從flag.enc文件中獲取flag
import rsa
k = rsa.PrivateKey(n,e,int(d),p,q)
f = open("flag.enc","rb+").read()
flag = rsa.decrypt(f,k)
print(flag)

flag{decrypt_256}

或者參考

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from base64 import b64decode
key_info = RSA.construct((n, e, d, p, q))
key = RSA.importKey(key_info.exportKey())
key = PKCS1_OAEP.new(key)
c = open('flag.enc', 'r').read()
flag = key.decrypt(c)
print(flag)

注意這個rsa.PrivateKey所有的參數都要是int

解法二

主要是獲取n,e的方法不同:

from Crypto.PublicKey import RSA

f = open("pub.key","rb").read()
pub = RSA.importKey(f)
print(pub.n,pub.e)

直接輸出86934482296048119190666062003494800588905656017203025617216654058378322103517 65537

BJDCTF 2nd rsa0

  1. 給了node3.buuoj.cn:29594,nc連接,得到

e = 13979291
p+q = 20977237986260593007660890508981067717396093749899360568870922582494976303967087098763078818179895715873024734793751951400162205998115419482795316817920280
p-q = -5049426131779840852071003122042677476051158981429628650820093396659375847153227632945712179794489294190510006561721934678066481600345373791000262601840042
c = 70438117942432148008990442238556447232354085811498412417829189204204737054074566374301936532846141586758014111171803840917548492915882174313587753182928014329241019646660166773180120124742002245739755885008339458315540236586607784113539202894986339079670203214801205209774217343754700849332717174826097340110

  1. Python代碼如下:
import gmpy2
from Crypto.Util.number import long_to_bytes

p_add_q = 20977237986260593007660890508981067717396093749899360568870922582494976303967087098763078818179895715873024734793751951400162205998115419482795316817920280
p_sub_q = -5049426131779840852071003122042677476051158981429628650820093396659375847153227632945712179794489294190510006561721934678066481600345373791000262601840042
c = 70438117942432148008990442238556447232354085811498412417829189204204737054074566374301936532846141586758014111171803840917548492915882174313587753182928014329241019646660166773180120124742002245739755885008339458315540236586607784113539202894986339079670203214801205209774217343754700849332717174826097340110
p = (p_add_q + p_sub_q)//2
q = (p_add_q - p_sub_q)//2
phn = (p - 1) * (q - 1)
e = 13979291
d = gmpy2.invert(e,phn)
n = p * q
m = pow(c,int(d),n)
print(long_to_bytes(m))

flag{2824f2c0-b958-4d96-9ce7-1b3d40e9333d}

BJDCTF 2nd rsa1

  1. nc node3.buuoj.cn 28900得到:

e = 10281503
p^2 + q^2 = 270444057910653983291510342788952455699025527244143860021628706211845060535465451636917932321742662851778396880163283934354651585000332834898540722361841525611785115213254272403844678168824876648088734737984008962948002087685706718428981545607421310961607011733185197994774655764395053430025157272336829270370
p - q=-1561498872519047771182262215325701201358158620347512518506157053314655896940102610797598167661629486698972575964893349157597071878670209310740687905237512
c = 130930373832526688558829060300851483713266963254235974298431376656411167133022811317545894728612430458019135516679725462401185182477034080725489312972647811206987019087112304263037750452464797665110487543936847345204903670608123393930724575428828772013286949081350478762423388787232374366710522714351275565934

  1. 根據pq的信息解方程即可,2(p^2 + q^2) - (p-q)^2 = (p+q)^2,emmm想用Python的cmath開根號或pow時會報溢出,所以整個解題過程在sage中實現。
  2. sage代碼如下:
import binascii
x = 270444057910653983291510342788952455699025527244143860021628706211845060535465451636917932321742662851778396880163283934354651585000332834898540722361841525611785115213254272403844678168824876648088734737984008962948002087685706718428981545607421310961607011733185197994774655764395053430025157272336829270370
p_sub_q = -1561498872519047771182262215325701201358158620347512518506157053314655896940102610797598167661629486698972575964893349157597071878670209310740687905237512
p_add_q = sqrt(2*x-pow(p_sub_q,2))
p = (p_add_q + p_sub_q)//2
q = (p_add_q - p_sub_q)//2
phn = (p - 1) * (q - 1)
e = 10281503
d = inverse_mod(e,phn)
n = p * q
c = 130930373832526688558829060300851483713266963254235974298431376656411167133022811317545894728612430458019135516679725462401185182477034080725489312972647811206987019087112304263037750452464797665110487543936847345204903670608123393930724575428828772013286949081350478762423388787232374366710522714351275565934
m=pow(c,d,n)
print(binascii.unhexlify(hex(m)[2:]))

flag{795faee7-4d4b-432c-9796-4758027c8a58}

RSAROLL

  1. data.txt中的數據如下:

{920139713,19}

704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148

  1. 把920139713拿到大數分解網站分解,發現可以分解成18443和49891。所以{920139713,19}應該是{n,e},剩下的行是密文。需要做的是循環求解每行的明文。
  2. 邏輯比較簡單。先由分解得到的p和q,以及已知的e求得d,然后讀取data.txt中的內容,循環求解明文。代碼如下:
import gmpy2

n = 920139713
e = 19
p = 18443
q = 49891
d = gmpy2.invert(e,(p-1)*(q-1))
f = open("data.txt","r")
flag = ""
for line in f.readlines()[2:]:
    # 從第三行開始讀
    c = int(line)
    flag += chr(pow(c,d,n))
print(flag)
f.close()

flag{13212je2ue28fy71w8u87y31r78eu1e2}

[HDCTF2019]basic rsa

  1. 題目attachment.py,具體代碼如下:
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

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

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551

e = 65533
n = p*q


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

print c

# 27565231154623519221597938803435789010285480123476977081867877272451638645710
  1. 所以基本邏輯很簡單,先通過p,q,e求d,上文已經有求解方法和案例。然后利用c,d,n求int(b2a_hex(flag),16)再反求flag。解題代碼如下:
import gmpy2
from binascii import a2b_hex

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551
e = 65533
c = 27565231154623519221597938803435789010285480123476977081867877272451638645710
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,p*q)
print(m)
flag = a2b_hex(hex(m)[2:])
print(flag)

注意這里m從10進制轉到16進制后,前面會有0x的前綴,所以取下標2及以后部分。flag{B4by_Rs4}

[GUET-CTF2019]BabyRSA

  1. 題目給了一個BabyRsa文件,用winhex打開發現這是一個文本文件,直接用記事本打開即可。有以下信息:

p + q : 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea
(p+1)(q+1) : 0x5248becef1d925d45705a7302700d6a0ffe5877fddf9451a9c1181c4d82365806085fd86fbaab08b6fc66a967b2566d743c626547203b34ea3fdb1bc06dd3bb765fd8b919e3bd2cb15bc175c9498f9d9a0e216c2dde64d81255fa4c05a1ee619fc1fc505285a239e7bc655ec6605d9693078b800ee80931a7a0c84f33c851740
e : 0xe6b1bee47bd63f615c7d0a43c529d219
d : 0x2dde7fbaed477f6d62838d55b0d0964868cf6efb2c282a5f13e6008ce7317a24cb57aec49ef0d738919f47cdcd9677cd52ac2293ec5938aa198f962678b5cd0da344453f521a69b2ac03647cdd8339f4e38cec452d54e60698833d67f9315c02ddaa4c79ebaa902c605d7bda32ce970541b2d9a17d62b52df813b2fb0c5ab1a5
enc_flag : 0x50ae00623211ba6089ddfae21e204ab616f6c9d294e913550af3d66e85d0c0693ed53ed55c46d8cca1d7c2ad44839030df26b70f22a8567171a759b76fe5f07b3c5a6ec89117ed0a36c0950956b9cde880c575737f779143f921d745ac3bb0e379c05d9a3cc6bf0bea8aa91e4d5e752c7eb46b2e023edbc07d24a7c460a34a9a

  1. 所以令x=p+q,y=(p+1)(q+1),就有n=p*q=y-x-1,這里給的e其實用不到。直接m=pow(enc_flag,d,n)就得到明文數據了,解題代碼如下:
from Crypto.Util.number import long_to_bytes
# x = p+q
# y = (p+1)(q+1)

x = 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea
y = 0x5248becef1d925d45705a7302700d6a0ffe5877fddf9451a9c1181c4d82365806085fd86fbaab08b6fc66a967b2566d743c626547203b34ea3fdb1bc06dd3bb765fd8b919e3bd2cb15bc175c9498f9d9a0e216c2dde64d81255fa4c05a1ee619fc1fc505285a239e7bc655ec6605d9693078b800ee80931a7a0c84f33c851740
d = 0x2dde7fbaed477f6d62838d55b0d0964868cf6efb2c282a5f13e6008ce7317a24cb57aec49ef0d738919f47cdcd9677cd52ac2293ec5938aa198f962678b5cd0da344453f521a69b2ac03647cdd8339f4e38cec452d54e60698833d67f9315c02ddaa4c79ebaa902c605d7bda32ce970541b2d9a17d62b52df813b2fb0c5ab1a5
enc_flag = 0x50ae00623211ba6089ddfae21e204ab616f6c9d294e913550af3d66e85d0c0693ed53ed55c46d8cca1d7c2ad44839030df26b70f22a8567171a759b76fe5f07b3c5a6ec89117ed0a36c0950956b9cde880c575737f779143f921d745ac3bb0e379c05d9a3cc6bf0bea8aa91e4d5e752c7eb46b2e023edbc07d24a7c460a34a9a

n = y - x - 1
m = pow(enc_flag,d,n)
print(long_to_bytes(m))

flag{cc7490e-78ab-11e9-b422-8ba97e5da1fd}

Buuoj RSA2

  1. 題目信息:

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

  1. 這是由dp求解p的問題。求解方法已在上文中有具體推導過程,解題代碼如下:
import gmpy2
from Crypto.Util.number import long_to_bytes

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657
c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

p = 0
for y in range(1,e):
    if (e*dp - 1)%y == 0:
        p = (e*dp - 1)//y + 1
        if n%p == 0:
            print(p)
            break
q = n // p
print(q)

d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(m))

flag{wow_leaking_dp_breaks_rsa?_98924743502}

Buuoj Dangerous RSA

  1. 題目提供的信息:

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

  1. 小指數明文爆破,前文已有原理。具體解題代碼如下:
import gmpy2
from Crypto.Util.number import long_to_bytes

n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e = 0x3
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

k = 0
while 1:
    if gmpy2.iroot(c+k*n,e)[1]==1:
        print(long_to_bytes(gmpy2.iroot(c+k*n,e)[0]))
        break
    k += 1

flag{25df8caf006ee5db94d48144c33b2c3b}

[GWCTF 2019]BabyRSA

  1. 解壓縮文件,有encrypt.py和secret,其中secret是文本文件,內容如下:

N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546

encrypt.py如下:

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()
  1. 由以上代碼可以得到以下表達式:
    \(c1=F1+F2\)
    \(c2=F1^{3}+F2^{3}\)
    \(c1=m1^{d}\ mod\ N\)
    \(c2=m2^{d}\ mod\ N\)
    d可由e,p,q求得。而p,q可通過yafu對N進行分解得到。所以拿到d后就可以求出c1和c2,然后解方程即可得到F1和F2,最后拼出flag。
  2. 解題代碼如下:
from Crypto.Util.number import long_to_bytes
from z3 import *
from gmpy2 import invert

N = 636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
p = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377748737
q = 797862863902421984951231350430312260517773269684958456342860983236184129602390919026048496119757187702076499551310794177917920137646835888862706126924088411570997141257159563952725882214181185531209186972351469946269508511312863779123205322378452194261217016552527754513215520329499967108196968833163329724620251096080377747699

m1 = 90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2 = 487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546

phn = (p-1) * (q-1)
e = 0x10001
d = invert(e,phn)
c1 = pow(m1,d,N)
c2 = pow(m2,d,N)
print("c1 =",c1)
print("c2 =",c2)

F1 = Int('F1')
F2 = Int('F2')
s = Solver()
s.add(F1 + F2 == int(c1))
s.add(F1**3 + F2**3 == int(c2))
if s.check()==sat:
    print(s.model())
print(long_to_bytes(1590956290598033029862556611630426044507841845)+long_to_bytes(1141553212031156130619789508463772513350070909))

GWHT{f709e0e2cfe7e530ca8972959a1033b2}

[HDCTF2019]bbbbbbrsa

  1. 題目給了enc和encode.py,內容如下:

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
  1. 所以思路是:先求c,這個c值不看代碼,直接從enc文本中就可以看出是逆序的base64結果,所以先逆序過來再base64解密即可;其次,由e爆破得到d;最后因為有\(c=int(b2a\_hex(flag),16)^{e}\ mod\ n\),所以有\(int(b2a\_hex(flag),16)=c^{d}\ mod\ n\),可整理得到flag,代碼如下:
from gmpy2 import invert,gcd
import base64
from Crypto.Util.number import long_to_bytes

p = 177077389675257695042507998165006460849
n = 37421829509887796274897162249367329400988647145613325367337968063341372726061
c = "==gMzYDNzIjMxUTNyIzNzIjMyYTM4MDM0gTMwEjNzgTM2UTN4cjNwIjN2QzM5ADMwIDNyMTO4UzM2cTM5kDN2MTOyUTO5YDM0czM3MjM"

q = n // p

c = str(c)[::-1]
c = base64.b64decode(c)
# c = 2373740699529364991763589324200093466206785561836101840381622237225512234632
print(c)

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

for e in range(50000,70000):
    if gcd(e,phi) == 1:
        d = invert(e,phi)
        x = pow(int(c),int(d),n)
        flag = str(long_to_bytes(x))
        if "flag" in flag or "CTF" in flag or "ctf" in flag:
            print(flag)

flag{rs4_1s_s1mpl3!#}

[BJDCTF2020]easyrsa

  1. 題目給了rsa_task.py,具體如下:
from Crypto.Util.number import getPrime,bytes_to_long
from sympy import Derivative
from fractions import Fraction
from secret import flag

p=getPrime(1024)
q=getPrime(1024)
e=65537
n=p*q
z=Fraction(1,Derivative(arctan(p),p))-Fraction(1,Derivative(arth(q),q))
m=bytes_to_long(flag)
c=pow(m,e,n)
print(c,z,n)
'''
output:
7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441
'''
  1. 所以基本思路是由z求出p和q,再有p,q,e得到d,由c,d,n求m即可得到最終的flag

  2. 由z求p,q。首先\(z=\frac{1}{arctan'(p)}\ -\ \frac{1}{arth'(q)}\),其中\(arctan'(p)=\frac{1}{1+p^{2}}\)\(arth'(q)=\frac{1}{1-q^{2}}\),因此有\(z=p^{2}+q^{2}\)。同時我們已知有\(n=pq\),z和n的值已知,利用z3庫聯立解方程即可。代碼如下:

from z3 import *

# z = p^2 + q^2
# n = p * q
z = 32115748677623209667471622872185275070257924766015020072805267359839059393284316595882933372289732127274076434587519333300142473010344694803885168557548801202495933226215437763329280242113556524498457559562872900811602056944423967403777623306961880757613246328729616643032628964072931272085866928045973799374711846825157781056965164178505232524245809179235607571567174228822561697888645968559343608375331988097157145264357626738141646556353500994924115875748198318036296898604097000938272195903056733565880150540275369239637793975923329598716003350308259321436752579291000355560431542229699759955141152914708362494482
n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441

p = Int('p')
q = Int('q')
s = Solver()
s.add(p**2 + q**2 == z)
s.add(p*q == n)
if s.check()==sat:
    print(s.model())

最終輸出可得:

p = 144564833334456076455156647979862690498796694770100520405218930055633597500009574663803955456004439398699669751249623406199542605271188909145969364476344963078599240058180033000440459281558347909876143313940657252737586803051935392596519226965519859474501391969755712097119163926672753588797180811711004203301
q = 105909195259921349656664570904199242969110902804477734660927330311460997899731622163728968380757294196277263615386525795293086103142131020215128282050307177125962302515483190468569376643751587606016315185736245896434947691528567696271911398179288329609207435393579332931583829355558784305002360873458907029141

  1. 由p,q,e,c,n求m,並得到flag
from Crypto.Util.number import *
from gmpy2 import invert

c = 7922547866857761459807491502654216283012776177789511549350672958101810281348402284098310147796549430689253803510994877420135537268549410652654479620858691324110367182025648788407041599943091386227543182157746202947099572389676084392706406084307657000104665696654409155006313203957292885743791715198781974205578654792123191584957665293208390453748369182333152809882312453359706147808198922916762773721726681588977103877454119043744889164529383188077499194932909643918696646876907327364751380953182517883134591810800848971719184808713694342985458103006676013451912221080252735948993692674899399826084848622145815461035
n = 15310745161336895413406690009324766200789179248896951942047235448901612351128459309145825547569298479821101249094161867207686537607047447968708758990950136380924747359052570549594098569970632854351825950729752563502284849263730127586382522703959893392329333760927637353052250274195821469023401443841395096410231843592101426591882573405934188675124326997277775238287928403743324297705151732524641213516306585297722190780088180705070359469719869343939106529204798285957516860774384001892777525916167743272419958572055332232056095979448155082465977781482598371994798871917514767508394730447974770329967681767625495394441
e = 65537
p = 144564833334456076455156647979862690498796694770100520405218930055633597500009574663803955456004439398699669751249623406199542605271188909145969364476344963078599240058180033000440459281558347909876143313940657252737586803051935392596519226965519859474501391969755712097119163926672753588797180811711004203301
q = 105909195259921349656664570904199242969110902804477734660927330311460997899731622163728968380757294196277263615386525795293086103142131020215128282050307177125962302515483190468569376643751587606016315185736245896434947691528567696271911398179288329609207435393579332931583829355558784305002360873458907029141
d = invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(m))

BJD{Advanced_mathematics_is_too_hard!!!}

Buuoj rsa2

  1. 題目是一個py文件,具體如下:
N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471
e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085

import hashlib
flag = "flag{" + hashlib.md5(hex(d)).hexdigest() + "}"
  1. 通過RSA Wiener Attack(維納攻擊)求得

d=8920758995414587152829426558580025657357328745839747693739591820283538307445

  1. 當在Python3環境下求解flag時報錯,提示要先編碼。但是我嘗試用utf-8和latin1編碼再求md5后,得到的flag提交還是不對,有點坑,最后還是用的Python2,flag的那行代碼不需要修改。最終結果為:

flag{47bf28da384590448e0b0d23909a25a4}

[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
'''

分析

  1. 前半部分可以得到(c,n,x已知):
      \(c=m^{e}\ mod\ n\)
    對第二個print出來的值如果設為x,有:
      \(x=294^{e}\ mod\ n\)

  2. 后半部分有(c2,m2,n2已知):
      \(c2=m2^{e}\ mod\ n2\)

  3. 解題首要目標自然是e,由於1中第二個表達式數值較小,本打算用sage求離散對數得到e但是跑不出來,所以用Python進行0,100000的遍歷找這個e的值

n = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
x = 381631268825806469518166370387352035475775677163615730759454343913563615970881967332407709901235637718936184198930226303761876517101208677107311006065728014220477966000620964056616058676999878976943319063836649085085377577273214792371548775204594097887078898598463892440141577974544939268247818937936607013100808169758675042264568547764031628431414727922168580998494695800403043312406643527637667466318473669542326169218665366423043579003388486634167642663495896607282155808331902351188500197960905672207046579647052764579411814305689137519860880916467272056778641442758940135016400808740387144508156358067955215018
for e in range(0,100000):
    if pow(294,e,n) == x:
        print(e)

得到e=52361

  1. 然后希望求得p,q的值以求d。但是想直接分解n的值太困難了。這里n和n2已知,且它們有最大公因數q,可直接求得,所以解題代碼如下:
from Crypto.Util.number import *
from gmpy2 import *

c = 12641635617803746150332232646354596292707861480200207537199141183624438303757120570096741248020236666965755798009656547738616399025300123043766255518596149348930444599820675230046423373053051631932557230849083426859490183732303751744004874183062594856870318614289991675980063548316499486908923209627563871554875612702079100567018698992935818206109087568166097392314105717555482926141030505639571708876213167112187962584484065321545727594135175369233925922507794999607323536976824183162923385005669930403448853465141405846835919842908469787547341752365471892495204307644586161393228776042015534147913888338316244169120
n = 13508774104460209743306714034546704137247627344981133461801953479736017021401725818808462898375994767375627749494839671944543822403059978073813122441407612530658168942987820256786583006947001711749230193542370570950705530167921702835627122401475251039000775017381633900222474727396823708695063136246115652622259769634591309421761269548260984426148824641285010730983215377509255011298737827621611158032976420011662547854515610597955628898073569684158225678333474543920326532893446849808112837476684390030976472053905069855522297850688026960701186543428139843783907624317274796926248829543413464754127208843070331063037
n2 = 12806210903061368369054309575159360374022344774547459345216907128193957592938071815865954073287532545947370671838372144806539753829484356064919357285623305209600680570975224639214396805124350862772159272362778768036844634760917612708721787320159318432456050806227784435091161119982613987303255995543165395426658059462110056431392517548717447898084915167661172362984251201688639469652283452307712821398857016487590794996544468826705600332208535201443322267298747117528882985955375246424812616478327182399461709978893464093245135530135430007842223389360212803439850867615121148050034887767584693608776323252233254261047
e = 52361
q = gcd(n,n2)
p = n // q
d = invert(e,(p-1)*(q-1))
flag = pow(c,d,n)
print(long_to_bytes(flag))

BJD{p_is_common_divisor}

[NCTF2019]babyRSA

題目代碼

from Crypto.Util.number import *
from flag import flag

def nextPrime(n):
    n += 2 if n & 1 else 1
    while not isPrime(n):
        n += 2
    return n

p = getPrime(1024)
q = nextPrime(p)
n = p * q
e = 0x10001
d = inverse(e, (p-1) * (q-1))
c = pow(bytes_to_long(flag.encode()), e, n)

# d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913
# c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804

解題過程

參考1
參考2

  1. e,d已知,先確定\(ed-1\)的位數。
import gmpy2

d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913
c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804
e = 0x10001

x = gmpy2.log2(e*d-1)
print(x)

結果為:2063.2545176257354
2. p的位數為1024,q在p的附近所以大致也是1024位。\(\phi(n)\)的位數約為2048,而\(ed-1\)大概是20632064位,所以$ed-1=1+x\phi(n)$中的x的位數為1516。
3. 在\(2^{15}\)~\(2^{16}\)減遍歷x,找到可以被x整除的\(ed-1\)。那么有\(\phi(n)=\frac{ed-1}{x}\)
4. 找到這個\(\phi(n)\),因此p和q大小相近,可以取\(\phi(n)\)平方根,在其附近的素數取為p,得到p值就很容易找到q,只要它們都是素數,將它們相乘得到n,隨即得到明文。
5. 解題代碼:

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

d = 19275778946037899718035455438175509175723911466127462154506916564101519923603308900331427601983476886255849200332374081996442976307058597390881168155862238533018621944733299208108185814179466844504468163200369996564265921022888670062554504758512453217434777820468049494313818291727050400752551716550403647148197148884408264686846693842118387217753516963449753809860354047619256787869400297858568139700396567519469825398575103885487624463424429913017729585620877168171603444111464692841379661112075123399343270610272287865200880398193573260848268633461983435015031227070217852728240847398084414687146397303110709214913
c = 5382723168073828110696168558294206681757991149022777821127563301413483223874527233300721180839298617076705685041174247415826157096583055069337393987892262764211225227035880754417457056723909135525244957935906902665679777101130111392780237502928656225705262431431953003520093932924375902111280077255205118217436744112064069429678632923259898627997145803892753989255615273140300021040654505901442787810653626524305706316663169341797205752938755590056568986738227803487467274114398257187962140796551136220532809687606867385639367743705527511680719955380746377631156468689844150878381460560990755652899449340045313521804
e = 0x10001
p = 0
q = 0
for x in range(2**15,2**16):
    if (e*d - 1) % x == 0:
        phn = (e*d - 1) // x
        p = nextprime(iroot(phn,2)[0])
        q = phn // (p-1) + 1
        if isPrime(q) and isPrime(p):
            print(p, q)
            break
# p = 143193611591752210918770476402384783351740028841763223236102885221839966637073188462808195974548579833368313904083095786906479416347681923731100260359652426441593107755892485944809419189348311956308456459523437459969713060653432909873986596042482699670451716296743727525586437248462432327423361080811225076497
# q = 143193611591752210918770476402384783351740028841763223236102885221839966637073188462808195974548579833368313904083095786906479416347681923731100260359652426441593107755892485944809419189348311956308456459523437459969713060653432909873986596042482699670451716296743727525586437248462432327423361080811225075839
n = p*q
m = pow(c,d,n)
print(long_to_bytes(m))

NCTF{70u2_nn47h_14_v3ry_gOO0000000d}

Reference

[1] https://baike.baidu.com/item/擴展歐幾里得算法/2029414?fr=aladdin
[2] FlappyPig.CTF特訓營
[3] https://www.freebuf.com/articles/database/170814.html?replytocom=249214


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM