羊城杯-2023-Crypto

news2024/11/28 16:46:32

文章目录

  • Danger_RSA
      • 题目描述:
      • 题目分析:
  • Easy_3L
      • 题目描述:
      • 题目分析:
  • XOR贯穿始终
      • 题目描述:
      • 题目分析:
  • MCeorpkpleer
      • 题目描述:
      • 题目分析:
  • SigninCrypto
      • 题目描述:
      • 题目分析:
  • esyRSA
      • 题目描述:
      • 题目分析:
  • 浅记一下

Danger_RSA

题目描述:

from Crypto.Util.number import *

m = bytes_to_long(flag)


def get_key(a, nbit):
    assert a >= 2
    while True:
        X = getRandomInteger(nbit // a)
        s = getRandomRange(pow(2, a ** 2 - a + 4), pow(2, a ** 2 - a + 5))
        p = X ** a + s
        if isPrime(p):
            return (p, s)

p, s = get_key(a, 1024)
q, t = get_key(a, 1024)

N = p * q
e = s * t
c = pow(m, e, N)
print("N =", N)
print("e =", e)
print("c =", c)

N = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766

题目分析:

e . n b i t s ( ) = 34 , 可知 s , t 分别为 17 b i t s , a 2 − a + 5 = 17 = > a = 4   ( 可以自己去测试这个结果 ) e.nbits() = 34,可知s,t分别为17bits,a^2 - a + 5 = 17=>a = 4 \ (可以自己去测试这个结果) e.nbits()=34,可知s,t分别为17bits,a2a+5=17=>a=4 (可以自己去测试这个结果)
简化一下 p = X 1 4 + s q = X 2 4 + t s , t 可通过 s a g e 中的 d i v i s i o n 函数分解得到 ( 通过是否为 17 b i t s 来进行取舍 ) ⇒ s , t 较小,那么 X 1 X 2 = i r o o t ( n , 4 ) [ 0 ] 又 n = ( X 1 4 + s ) ∗ ( X 2 4 + t ) 联立两个方程求解得到 X 1 , X 2 , 那么 p , q 也就出来了 简化一下\\ p = X_1 ^ {4} + s\\ q = X_2 ^ {4} + t\\ s,t可通过sage中的division函数分解得到\\(通过是否为17bits来进行取舍)\\ \Rightarrow s,t较小,那么X_1X_2 = iroot(n,4)[0]\\ 又n = (X_1 ^ {4} + s) * (X_2 ^ {4} + t)\\ 联立两个方程求解得到X_1,X_2,那么p,q也就出来了 简化一下p=X14+sq=X24+ts,t可通过sage中的division函数分解得到(通过是否为17bits来进行取舍)s,t较小,那么X1X2=iroot(n,4)[0]n=(X14+s)(X24+t)联立两个方程求解得到X1,X2,那么p,q也就出来了

# sage
from gmpy2 import *
from Crypto import *
n = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766

# a = divisors(e)
# for i in a:
#     if i.nbits() == 17 and (e // i).nbits() == 17:
#         print(i)
#         print(e // i)

r,s = 91903,120561
X1X2 = int(iroot(n,4)[0])

# X1,X2 = var('X1 X2')
# f1 = X1 * X2 == X1X2
# f2 = (X1 ** 4 + s) * (X2 ** 4 + t) == n
# print(solve([f1,f2],[a,b]))

a = 44416071018427916652440592614276227563515579156219730344722242565477265479486
b = 47783641287938625512681830427927501009821495321018170621907812035456872958654
p = a ** 4 + r
q = b ** 4 + s

可以发现gcd(e,p - 1)与gcd(e,q-1)都不为1,(e,p-1) = 49,(e,q-1) = 3。又p,q长度为1024,比flag大得多,可直接进行在模p或q下的有限域开方,之后再遍历即可得到flag

# 承接上面代码
d = invert(e // 3,(q - 1))
m_3 = pow(c,d,q)
e = 3
R.<x> = Zmod(q)[]
f=x^e-m_3
mps=f.monic().roots()

for i in mps:
    flag=long_to_bytes(int(i[0]))
    if b'CTF' in flag:
        print(flag) 

# b'DASCTF{C0nsTruct!n9_Techn1qUe2_f0r_RSA_Pr1me_EnC2ypt10N}'

拓展:
AMM算法求解:

import random
import time
from tqdm import tqdm
from Crypto.Util.number import *
# About 3 seconds to run
def AMM(o, r, q):
    start = time.time()
    print('\n----------------------------------------------------------------------------------')
    print('Start to run Adleman-Manders-Miller Root Extraction Method')
    print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q))
    g = GF(q)
    o = g(o)
    p = g(random.randint(1, q))
    while p ^ ((q-1) // r) == 1:
        p = g(random.randint(1, q))
    print('[+] Find p:{}'.format(p))
    t = 0
    s = q - 1
    while s % r == 0:
        t += 1
        s = s // r
    print('[+] Find s:{}, t:{}'.format(s, t))
    k = 1
    while (k * s + 1) % r != 0:
        k += 1
    alp = (k * s + 1) // r
    print('[+] Find alp:{}'.format(alp))
    a = p ^ (r**(t-1) * s)
    b = o ^ (r*alp - 1)
    c = p ^ s
    h = 1
    for i in range(1, t):
        d = b ^ (r^(t-1-i))
        if d == 1:
            j = 0
        else:
            print('[+] Calculating DLP...')
            j = - discrete_log(d, a)
            print('[+] Finish DLP...')
        b = b * (c^r)^j
        h = h * c^j
        c = c^r
    result = o^alp * h
    end = time.time()
    print("Finished in {} seconds.".format(end - start))
    print('Find one solution: {}'.format(result))
    return result

def onemod(p,r): 
    t=random.randint(2,p)
    while pow(t,(p-1)//r,p)==1: 
         t=random.randint(2,p)
    return pow(t,(p-1)//r,p) 
 
def solution(p,root,e):  
    while True:
        g=onemod(p,e) 
        may=[] 
        for i in tqdm(range(e)): 
            may.append(root*pow(g,i,p)%p)
        if len(may) == len(set(may)):
            return may


def solve_in_subset(ep,p):
    cp = int(pow(c,inverse(int(e//ep),p-1),p))
    com_factors = []
    while GCD(ep,p-1) !=1:
        com_factors.append(GCD(ep,p-1))
        ep //= GCD(ep,p-1)
    com_factors.sort()

    cps = [cp]
    for factor in com_factors:
        mps = []
        for cp in cps:
            mp = AMM(cp, factor, p)
            mps += solution(p,mp,factor)
        cps = mps
    for each in cps:
        assert pow(each,e,p)==c%p
    return cps

n = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
p = 3891889986375336330559716098591764128742918441309724777337583126578227827768865619689858547513951476952436981068109005313431255086775128227872912287517417948310766208005723508039484956447166240210962374423348694952997002274647622939970550008327647559433222317977926773242269276334110863262269534189811138319
q = 5213351003420231819415242686664610206224730148063270274863722096379841592931572096469136339538500817713355302889731144789372844731378975059329731297860686270736540109105854515590165681366189003405833252270606896051264517339339578167231093908235856718285980689179840159807651185918046198419707669304960745217
ep = 49
eq = 3

m_p = solve_in_subset(ep,p)
m_q = solve_in_subset(eq,q)

start = time.time()
print('Start CRT...')
for mpp in m_p:
    for mqq in m_q:
        solution = CRT_list([int(mpp), int(mqq)], [p, q])
        if solution < 2^800 :   # Always the bit_length of flag is less than 800
            print(long_to_bytes(solution))

end = time.time()
print("Finished in {} seconds.".format(end - start))

# b'DASCTF{C0nsTruct!n9_Techn1qUe2_f0r_RSA_Pr1me_EnC2ypt10N}'

Easy_3L

题目描述:

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

m = bytes_to_long(flag)


def get_key():
    p = getPrime(1400)
    f = getRandomNBitInteger(1024)
    while True:
        q = getPrime(512)
        if gcd(f, q) != 1:
            continue
        else:
            break
    h = (invert(f, p) * q) % p
    return p, h


def encrypt1(m):
    a = getPrime(250)
    b = getRandomNBitInteger(240)
    n = getPrime(512)
    seed = m
    s = [0] * 6
    s[0] = seed
    for i in range(1, 6):
        s[i] = (s[i - 1] * a + b) % n
    return s


def encrypt2(msg, p, h):
    s = getRandomNBitInteger(512)
    c = (s * h + msg) % p
    return c


s = encrypt1(m)
print("S1 =", s[1])
print("S2 =", s[2])
print("S4 =", s[4])
print("S5 =", s[5])

p, h = get_key()
c = encrypt2(s[3], p, h)
print("p =", p)
print("h =", h)
print("c =", c)

# S1 = 28572152986082018877402362001567466234043851789360735202177142484311397443337910028526704343260845684960897697228636991096551426116049875141
# S2 = 1267231041216362976881495706209012999926322160351147349200659893781191687605978675590209327810284956626443266982499935032073788984220619657447889609681888
# S4 = 9739918644806242673966205531575183334306589742344399829232076845951304871478438938119813187502023845332528267974698273405630514228632721928260463654612997
# S5 = 9755668823764800147393276745829186812540710004256163127825800861195296361046987938775181398489372822667854079119037446327498475937494635853074634666112736
# p = 25886434964719448194352673440525701654705794467884891063997131230558866479588298264578120588832128279435501897537203249743883076992668855905005985050222145380285378634993563571078034923112985724204131887907198503097115380966366598622251191576354831935118147880783949022370177789175320661630501595157946150891275992785113199863734714343650596491139321990230671901990010723398037081693145723605154355325074739107535905777351
# h = 2332673914418001018316159191702497430320194762477685969994411366563846498561222483921873160125818295447435796015251682805613716554577537183122368080760105458908517619529332931042168173262127728892648742025494771751133664547888267249802368767396121189473647263861691578834674578112521646941677994097088669110583465311980605508259404858000937372665500663077299603396786862387710064061811000146453852819607311367850587534711
# c = 20329058681057003355767546524327270876901063126285410163862577312957425318547938475645814390088863577141554443432653658287774537679738768993301095388221262144278253212238975358868925761055407920504398004143126310247822585095611305912801250788531962681592054588938446210412897150782558115114462054815460318533279921722893020563472010279486838372516063331845966834180751724227249589463408168677246991839581459878242111459287

题目分析:

唉,前面h = (invert(f, p) * q) % p真的是,一直盯着这里看,没往后看,花了好多时间。唉,题目还是要先完整看下来啊。
进入正题
考点在c = (s * h + S[3]) % p这串
c = ( s ∗ h + S [ 3 ] ) % p S [ 3 ] = c − s ∗ h + k ∗ p 构造如下格   M = ( 2 512 c 1 h p )   ( 1 , − s , k ) ∗ M = ( 2 512 , − s , S [ 3 ] )   L L L 之后得到 S [ 3 ] , 之后直接 L C G 求解即可得到 f l a g c = (s * h + S[3]) \% p \\ S[3] = c - s * h + k * p\\ 构造如下格\\ \ \\ M = \begin{pmatrix} 2^{512}&&c\\ &1&h\\ &&p \end{pmatrix}\\ \ \\ (1,-s,k) * M = (2 ^ {512},-s,S[3])\\ \ \\ LLL之后得到S[3],之后直接LCG求解即可得到flag c=(sh+S[3])%pS[3]=csh+kp构造如下格 M= 25121chp  (1,s,k)M=(2512,s,S[3]) LLL之后得到S[3],之后直接LCG求解即可得到flag
3L:

from Crypto.Util.number import *
from gmpy2 import *
p = 25886434964719448194352673440525701654705794467884891063997131230558866479588298264578120588832128279435501897537203249743883076992668855905005985050222145380285378634993563571078034923112985724204131887907198503097115380966366598622251191576354831935118147880783949022370177789175320661630501595157946150891275992785113199863734714343650596491139321990230671901990010723398037081693145723605154355325074739107535905777351
h = 2332673914418001018316159191702497430320194762477685969994411366563846498561222483921873160125818295447435796015251682805613716554577537183122368080760105458908517619529332931042168173262127728892648742025494771751133664547888267249802368767396121189473647263861691578834674578112521646941677994097088669110583465311980605508259404858000937372665500663077299603396786862387710064061811000146453852819607311367850587534711
c = 20329058681057003355767546524327270876901063126285410163862577312957425318547938475645814390088863577141554443432653658287774537679738768993301095388221262144278253212238975358868925761055407920504398004143126310247822585095611305912801250788531962681592054588938446210412897150782558115114462054815460318533279921722893020563472010279486838372516063331845966834180751724227249589463408168677246991839581459878242111459287

M = matrix(ZZ,[[2 ** 512,0,c],[0,1,h],[0,0,p]])
M = M.LLL()
S3 = abs(M[0][-1])

# 10700695166096094995375972320865971168959897437299342068124161538902514000691034236758289037664275323635047529647532200693311709347984126070052011571264606

LCG:

import gmpy2
from Crypto.Util.number import *
# 逆元求法
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] # 逆元计算
S1 = 28572152986082018877402362001567466234043851789360735202177142484311397443337910028526704343260845684960897697228636991096551426116049875141
S2 = 1267231041216362976881495706209012999926322160351147349200659893781191687605978675590209327810284956626443266982499935032073788984220619657447889609681888
S3 = 10700695166096094995375972320865971168959897437299342068124161538902514000691034236758289037664275323635047529647532200693311709347984126070052011571264606
S4 = 9739918644806242673966205531575183334306589742344399829232076845951304871478438938119813187502023845332528267974698273405630514228632721928260463654612997
S5 = 9755668823764800147393276745829186812540710004256163127825800861195296361046987938775181398489372822667854079119037446327498475937494635853074634666112736
s = [S1,S2,S3,S4,S5]
t = []

for i in range(4): # len(out) - 1
    t.append(s[i+1]-s[i])

for i in range(1): 
    n = gmpy2.gcd(t[i+3] * t[i+1] - t[i+2] * t[i+2],t[i+2] * t[i] - t[i+1] * t[i+1])
    inv = MMI(s[1] - s[0], n) % n
    a = (s[2] - s[1]) * inv % n
    b = (s[1] - a * s[0]) % n
    inv_a = MMI(a, n)
    seed = (s[0] - b) * inv_a % n
    print(long_to_bytes(seed))
    
# b'DASCTF{NTRU_L0G_a6e_S1mpLe}'

XOR贯穿始终

题目描述:

自由和谐和谐富强公正友善爱国公正法治法治文明和谐自由法治自由法治平等公正友善公正公正民主法治自由公正敬业和谐富强公正友善爱国和谐平等平等友善敬业法治敬业和谐富强法治平等平等友善敬业公正公正公正友善敬业法治平等平等诚信自由公正自由平等友善敬业公正友善法治和谐和谐

【解码得到C0ngr4tulati0n5_y0u_fou^d_m3作为下面两个文件的密码】

from gmpy2 import gcd
from Crypto.Util.number import getPrime
from secret import enflag

p = getPrime(512)
q = getPrime(512)
n = q * p
phi = (p - 1) * (q - 1)
e = getPrime(17)
assert gcd(e, phi) == 1
# 以上信息生成了私钥文件,但文件被损坏了你能提取有用信息吗

c = pow(enflag, e, n)
print('c = ' + str(c))

'''
c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818
'''
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALmtMy+2uH1ZtbIL
SuiAukFthyQRH5mp7UmLyzZQkdg9zEP9/5tgffikQ7ytx5kHySHnazgAO1sOzmYE
N4Axlev6uafiP8B1Eij97v5VkYJ1I9e3mtBNheTbXKoT8op+ASQ1fQaF4A8UzLuW
eZeZI8JTH/SH+bolAK3kiZXDFdkTAgMBAAECgYEAl067LaC7Cvs2A5cMPhfYsESv
IgcKN1CwW4Sd3u8dSphhgu7TgyzIuvwxbuo2g1BC6WwKhaI6vGN+csfw6nh98GEn
/p3D0huNroAYvf/DRRB9UnHdttX7wB+Mv3P0RBDWHgBiCDVvHFuFUV78cIs0tnbn
jxjU07aPV2XRC3AfA2ECQQDqWUNPVg3i6vTyHCL7EGkbeUheYpAAfcKCQrxjc5+5
X6A+XtgHAA1JHwykPlCpHUOmlA85DJF1ejuoImzlgRLJAkEAytTCnQF+MN2r1gaA
UETZyj5qMYT7Th8zKEVVVJjDawLnuX4usJ2FyRnjCkk86U75QSJhw5mMc0QnG25u
Gz3++w==
-----END PRIVATE KEY-----

题目分析:

以上信息生成了私钥文件,但文件被损坏了你能提取有用信息吗
细节看这篇文章
至此可以得到n,e,p,q
标题XOR贯穿始终,rsa得到的m与C0ngr4tulati0n5_y0u_fou^d_m3异或即可得到flag

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

c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818
n = 0x00b9ad332fb6b87d59b5b20b4ae880ba416d8724111f99a9ed498bcb365091d83dcc43fdff9b607df8a443bcadc79907c921e76b38003b5b0ece660437803195ebfab9a7e23fc0751228fdeefe5591827523d7b79ad04d85e4db5caa13f28a7e0124357d0685e00f14ccbb9679979923c2531ff487f9ba2500ade48995c315d913
e = 0x10001
p = 0xea59434f560de2eaf4f21c22fb10691b79485e6290007dc28242bc63739fb95fa03e5ed807000d491f0ca43e50a91d43a6940f390c91757a3ba8226ce58112c9
q = 0xcad4c29d017e30ddabd606805044d9ca3e6a3184fb4e1f332845555498c36b02e7b97e2eb09d85c919e30a493ce94ef9412261c3998c7344271b6e6e1b3dfefb

phi = (p-1)*(q-1)
d = invert(e,phi)
m = pow(c,d,n)
mm = b'C0ngr4tulati0n5_y0u_fou^d_m3'
print(long_to_bytes(m ^ bytes_to_long(mm)))

# b'DASCTF{0e2874af5e422482378640e61d919e9a}'

MCeorpkpleer

题目描述:

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

def pubkey(list, m, w):
    pubkey_list = []
    for i in range(len(e_bin)):
        pubkey_list.append(w * list[i] % m)
    return pubkey_list

def e_cry(e, pubkey):
    pubkey_list = pubkey
    encode = 0
    for i in range(len(e)):
        encode += pubkey_list[i] * int(e[i]) % m
    return encode

p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = getPrime(64)
m = bytes_to_long(flag)
c = pow(m, e, n)

e_bin = (bin(e))[2:]
list = [pow(3, i) for i in range(len(e_bin))]
m = getPrime(len(bin(sum(list))) - 1)
w = getPrime(64)
pubkey = pubkey(list, m, w)
en_e = e_cry(e_bin, pubkey)

print('p = {}\n'
      'n = {}\n'
      'c = {}\n'
      'pubkey = {}\n'
      'en_e = {}'.format((p >> 435) << 435, n, c, pubkey, en_e))

p = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179655351110456639347861739783538289295071556484465877192913103980697449775104351723521120185802327587352171892429135110880845830815744
n = 22687275367292715121023165106670108853938361902298846206862771935407158965874027802803638281495587478289987884478175402963651345721058971675312390474130344896656045501040131613951749912121302307319667377206302623735461295814304029815569792081676250351680394603150988291840152045153821466137945680377288968814340125983972875343193067740301088120701811835603840224481300390881804176310419837493233326574694092344562954466888826931087463507145512465506577802975542167456635224555763956520133324723112741833090389521889638959417580386320644108693480886579608925996338215190459826993010122431767343984393826487197759618771
c = 156879727064293983713540449709354153986555741467040286464656817265584766312996642691830194777204718013294370729900795379967954637233360644687807499775502507899321601376211142933572536311131955278039722631021587570212889988642265055045777870448827343999745781892044969377246509539272350727171791700388478710290244365826497917791913803035343900620641430005143841479362493138179077146820182826098057144121231954895739989984846588790277051812053349488382941698352320246217038444944941841831556417341663611407424355426767987304941762716818718024107781873815837487744195004393262412593608463400216124753724777502286239464
pubkey = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
en_e = 31087054322877663244023458448558

题目分析:

len(e_bin) = 64(通过pubkey的长度得知),由此list便知道了
容易得知list的第一个就是w,w知道了那么m也就好知道了

list1 = []
for i in list:
    list1.append(w * i)
print(list1)

# list1 = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 5124319825861712660827229328537, 15372959477585137982481687985611, 46118878432755413947445063956833, 138356635298266241842335191870499, 415069905894798725527005575611497, 1245209717684396176581016726834491, 3735629153053188529743050180503473, 11206887459159565589229150541510419, 33620662377478696767687451624531257, 100861987132436090303062354873593771, 302585961397308270909187064620781313, 907757884191924812727561193862343939, 2723273652575774438182683581587031817, 8169820957727323314548050744761095451, 24509462873181969943644152234283286353, 73528388619545909830932456702849859059, 220585165858637729492797370108549577177, 661755497575913188478392110325648731531, 1985266492727739565435176330976946194593, 5955799478183218696305528992930838583779, 17867398434549656088916586978792515751337, 53602195303648968266749760936377547254011, 160806585910946904800249282809132641762033, 482419757732840714400747848427397925286099, 1447259273198522143202243545282193775858297, 4341777819595566429606730635846581327574891, 13025333458786699288820191907539743982724673, 39076000376360097866460575722619231948174019, 117228001129080293599381727167857695844522057, 351684003387240880798145181503573087533566171, 1055052010161722642394435544510719262600698513, 3165156030485167927183306633532157787802095539, 9495468091455503781549919900596473363406286617, 28486404274366511344649759701789420090218859851, 85459212823099534033949279105368260270656579553, 256377638469298602101847837316104780811969738659, 769132915407895806305543511948314342435909215977, 2307398746223687418916630535844943027307727647931, 6922196238671062256749891607534829081923182943793, 20766588716013186770249674822604487245769548831379]
# list0 = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
# m = 5124319825861712660827229328537 - 601827224419797931380408071500
# print(m)

m = 4522492601441914729446821257037

w = 18143710780782459577
m = 4522492601441914729446821257037

简化一下: e _ b i n = b i n ( e ) = ( e 1 , e 2 , . . . e 64 ) p u b k e y = ( p u b 1 , p u b 2 , . . . , p u b 64 ) 其中 e i 均为 0 或 1 e n _ e ≡ p u b 1 ∗ e 1 + p u b 2 ∗ e 2 + . . . + p u b 64 ∗ e 64 ( m o d m ) ⇒ e n _ e = p u b 1 ∗ e 1 + p u b 2 ∗ e 2 + . . . + p u b 64 ∗ e 64 + k ∗ m 0 = p u b 1 ∗ e 1 + p u b 2 ∗ e 2 + . . . + p u b 64 ∗ e 64 − e n _ e + k ∗ m   构造如下格:   M = ( 1 p u b 1 1 p u b 2 ⋱ ⋮ 1 p u b 64 1 e n _ e m )   ( e 1 , e 2 , . . . , e 64 , − 1 , k ) ∗ M = ( e 1 , e 2 , . . . , e 64 , − 1 , 0 ) 简化一下:\\ e\_bin = bin(e) = (e_1,e_2,...e_{64})\\ pubkey = (pub_1,pub_2,...,pub_{64})\\ 其中e_i均为0或1\\ en\_e \equiv pub_1 * e_1 + pub_2 * e_2 + ... + pub_{64} * e_{64} \pmod m\\ \Rightarrow en\_e = pub_1 * e_1+ pub_2 * e_2 + ... + pub_{64} * e_{64} + k * m\\ 0 = pub_1 * e_1+ pub_2 * e_2 + ... + pub_{64} * e_{64} -en\_e + k * m\\ \ \\ 构造如下格:\\ \ \\ M = \begin{pmatrix} 1&&&&&pub_1\\ &1&&&&pub_2\\ &&\ddots&&&\vdots\\&&&1&&pub_{64}\\ &&&&1&en\_e\\&&&&&m \end{pmatrix}\\ \ \\ (e_1,e_2,...,e_{64},-1,k) * M = (e_1,e_2,...,e_{64},-1,0)\\ 简化一下:e_bin=bin(e)=(e1,e2,...e64)pubkey=(pub1,pub2,...,pub64)其中ei均为01en_epub1e1+pub2e2+...+pub64e64(modm)en_e=pub1e1+pub2e2+...+pub64e64+km0=pub1e1+pub2e2+...+pub64e64en_e+km 构造如下格: M= 1111pub1pub2pub64en_em  (e1,e2,...,e64,1,k)M=(e1,e2,...,e64,1,0)

from Crypto.Util.number import *
from hashlib import md5
m = 4522492601441914729446821257037
pubkey = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
en_e = 31087054322877663244023458448558

M = matrix(ZZ,66,66)

for i in range(64):
    M[i,i] = 1
    M[i,-1] = pubkey[i]

M[-2,-2] = 1
M[-2,-1] = en_e
M[-1,-1] = m

L = M.BKZ()
print(L)

想不到的是目标向量竟然在中间一行,一度以为我求错了,哭死

e_bin = [-1,-1,0,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,0,-1,-1,0,-1,0,0,-1,-1,-1,0,-1,0,0,0,0,0,0,-1,0,0,0,0,-1,0,0,0,0,-1,0,-1,0,0,-1,-1]
e = ''
for i in m:
    if i == 1 or i == -1:
        e += '1'
    else:
        e += '0'
        
e = int(e_bin,2)
# e = 15960663600754919507

高位攻击求到p,之后常规rsa

# sage
from gmpy2 import *
from Crypto.Util.number import *
p_high = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179655351110456639347861739783538289295071556484465877192913103980697449775104351723521120185802327587352171892429135110880845830815744
n = 22687275367292715121023165106670108853938361902298846206862771935407158965874027802803638281495587478289987884478175402963651345721058971675312390474130344896656045501040131613951749912121302307319667377206302623735461295814304029815569792081676250351680394603150988291840152045153821466137945680377288968814340125983972875343193067740301088120701811835603840224481300390881804176310419837493233326574694092344562954466888826931087463507145512465506577802975542167456635224555763956520133324723112741833090389521889638959417580386320644108693480886579608925996338215190459826993010122431767343984393826487197759618771
pbits = 1024
kbits = 435
PR.<x> = PolynomialRing(Zmod(n))
f = x + p_high
p0 = f.small_roots(X = 2 ^ kbits,beta = 0.4)[0]
# print(p_high + p0)

p = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179677630589032444985150800881889090713797496239571291907818169058929859395965304623825442220206712660451198754072531986630133689525911
c = 156879727064293983713540449709354153986555741467040286464656817265584766312996642691830194777204718013294370729900795379967954637233360644687807499775502507899321601376211142933572536311131955278039722631021587570212889988642265055045777870448827343999745781892044969377246509539272350727171791700388478710290244365826497917791913803035343900620641430005143841479362493138179077146820182826098057144121231954895739989984846588790277051812053349488382941698352320246217038444944941841831556417341663611407424355426767987304941762716818718024107781873815837487744195004393262412593608463400216124753724777502286239464
e = 15960663600754919507
q = n // p
d = invert(e,(p-1)*(q-1))
print(long_to_bytes(int(pow(c,d,n))))

# b'DASCTF{T81I_tPPS_6r7g_xlPi_OO3M_6vyV_Rkba}'

看完星盟安全团队的wp知道了另一种更简单的解法,通过利用超递增序列求解
en_e = (pub1 * e1) % m + ...+ (pub64 * e64) % m
又pubi = w * listi % m
=> en_e = w * (list1 * e1 + ... + list64 * e64) % m
= > e n _ e ∗ w − 1 ≡ ( l i s t 1 ∗ e 1 + . . . + l i s t 64 ∗ e 64 ) ( m o d m ) => en\_e * w ^ {-1} \equiv (list1 * e1 + ... + list64 * e64) \pmod m =>en_ew1(list1e1+...+list64e64)(modm)
其中list是超递增序列
贴一下他们超递增解题代码:

## SageMath
import libnum, gmpy2
pubkey = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
en_e = 31087054322877663244023458448558
w = gcd(pubkey[0], pubkey[1])
assert is_prime(w)
list1 = [pow(3, i) for i in range(64)]
m = gcd(w*list1[-1]-pubkey[-1], w*list1[-2]-pubkey[-2])
assert is_prime(m)

en_e = en_e *inverse_mod(w,m) % m
e = ''
for each in list1[::-1]:
    if en_e >= each:
        e += '1'
        en_e -= each
    else:
        e += '0'

e = int(e[::-1], 2)
p0 = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179655351110456639347861739783538289295071556484465877192913103980697449775104351723521120185802327587352171892429135110880845830815744
n = 22687275367292715121023165106670108853938361902298846206862771935407158965874027802803638281495587478289987884478175402963651345721058971675312390474130344896656045501040131613951749912121302307319667377206302623735461295814304029815569792081676250351680394603150988291840152045153821466137945680377288968814340125983972875343193067740301088120701811835603840224481300390881804176310419837493233326574694092344562954466888826931087463507145512465506577802975542167456635224555763956520133324723112741833090389521889638959417580386320644108693480886579608925996338215190459826993010122431767343984393826487197759618771
c = 156879727064293983713540449709354153986555741467040286464656817265584766312996642691830194777204718013294370729900795379967954637233360644687807499775502507899321601376211142933572536311131955278039722631021587570212889988642265055045777870448827343999745781892044969377246509539272350727171791700388478710290244365826497917791913803035343900620641430005143841479362493138179077146820182826098057144121231954895739989984846588790277051812053349488382941698352320246217038444944941841831556417341663611407424355426767987304941762716818718024107781873815837487744195004393262412593608463400216124753724777502286239464

kbit = 435
PR.<x> = PolynomialRing(Zmod(n))
f = p0+x
x = f.small_roots(X=2^kbit, beta=0.4)
p = p0+int(x[0])
q = n // p
d = int(gmpy2.invert(e, (p-1)*(q-1)))
m = int(pow(c, d, n))
print(libnum.n2s(m))  # DASCTF{T81I_tPPS_6r7g_xlPi_OO3M_6vyV_Rkba}

SigninCrypto

题目描述:

from random import *
from Crypto.Util.number import *
from Crypto.Cipher import DES3
from flag import flag
from key import key
from iv import iv
import os
import hashlib
import secrets

K1 = key
hint1 = os.urandom(2) * 8
xor =bytes_to_long(hint1)^bytes_to_long(K1)
print(xor)

def Rand():
    rseed = secrets.randbits(1024)
    List1 = []
    List2 = []
    seed(rseed)
    for i in range(624):
        rand16 = getrandbits(16)
        List1.append(rand16)
    seed(rseed)
    for i in range(312):
        rand64 = getrandbits(64)
        List2.append(rand64)
    with open("task.txt", "w") as file:
        for rand16 in List1:
            file.write(hex(rand16)+ "\n")
        for rand64 in List2:
            file.write(hex((rand64 & 0xffff) | ((rand64 >> 32) & 0xffff) << 16) + "\n") # 低16位
Rand()

K2 = long_to_bytes(getrandbits(64))
K3 = flag[:8]

KEY = K1 + K2 + K3

IV=iv

IV1=IV[:len(IV)//2]
IV2=IV[len(IV)//2:]

digest1 = hashlib.sha512(IV1).digest().hex()
digest2 = hashlib.sha512(IV2).digest().hex()

digest=digest1+digest2
hint2=(bytes_to_long(IV)<<32)^bytes_to_long(os.urandom(8))
print(hex(bytes_to_long((digest.encode()))))
print(hint2)


mode = DES3.MODE_CBC
des3 = DES3.new(KEY, mode, IV)

pad_len = 8 - len(flag) % 8
padding = bytes([pad_len]) * pad_len
flag += padding

cipher = des3.encrypt(flag)

ciphertext=cipher.hex()
print(ciphertext)

xor = 334648638865560142973669981316964458403
digest_encode = 0x62343937373634656339396239663236643437363738396663393438316230353665353733303939613830616662663633326463626431643139323130616333363363326631363235313661656632636265396134336361623833636165373964343533666537663934646239396462323666316236396232303539336438336234393737363465633939623966323664343736373839666339343831623035366535373330393961383061666266363332646362643164313932313061633336336332663136323531366165663263626539613433636162383363616537396434353366653766393464623939646232366631623639623230353933643833
hint2 = 22078953819177294945130027344
ciphertext = 'a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1'

题目分析:

在这里插入图片描述

猜测hint1 = b’\xfb\xc2’ * 8

异或得到K1 = dasctfda

(K2先跳过,最后来说)

flag前7位为DASCTF{

K3 = flag[:8],即flag前8位,这意味着K3也差不多出来了,爆破一位即可

(K2,K3都是8位,那K1很大概率就是8位,所以上面求出的K1是正确的)

hint2长度95,95-32 = 63,可以知道IV是64位(前导0省略了)

可以求出IV的前4个字节(32bits)为GWHT,由此得到IV1 = GWHT

知道了digest_encode,又知道了IV1,那么IV2也可以求出来

digest1 = hashlib.sha512(IV1).digest().hex()
digest2 = hashlib.sha512(IV2).digest().hex()
digest=digest1+digest2
hint2=(bytes_to_long(IV)<<32)^bytes_to_long(os.urandom(8)) 

IV1 = b'GWHT'
digest1 = hashlib.sha512(IV1).digest().hex()
digest11 = bytes_to_long(digest1.encode())
digest2 = long_to_bytes((digest_encode - (digest11 << (8 * 128))))

print(digest2)可以发现digest2 = digest1,由此可知IV2 = IV1 = GWHT

由此未知量都出来了,只剩K2了

随机数生成机制:都是通过生成32bits的数
生成16bits:先生成32bits,再取此数高16位
生成64bits:先生成两个32bits的数X1,X2,再拼接X2||X1

知道了生成机制,那么K2也就能出来了

for i in range(624):
        rand16 = getrandbits(16)

从这里我们知道了624个32bits数的高16位

file.write(hex((rand64 & 0xffff) | ((rand64 >> 32) & 0xffff) << 16) + "\n")

从这里我们知道了624个32bits数的低16位

拼接一下即可得到624个32bits数,之后便是普普通通的随机数预测了

至此所有未知量都出来了,flag也就出来了
完整代码如下:

from Crypto.Util.number import *
from randcrack import RandCrack
from Crypto.Cipher import DES3

with open('task.txt','r') as f:
    f = f.readlines()

data = [eval(i) for i in f]
ran16 = data[:624]
ran64 = data[-312:]
ran64_ = []
for i in ran64:
    ran64_.append(i & 0xffff)
    ran64_.append(i >> 16)

ran32 = []
for i in range(624):
    ran32.append((ran16[i] << 16) + ran64_[i])

rc = RandCrack()
for i in ran32:
    rc.submit(i)

K2 = long_to_bytes(rc.predict_getrandbits(64))
K1 = b'dasctfda'
IV1 = b'GWHT'
IV2 = b'GWHT'
IV = IV1 + IV2
ciphertext = 'a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1'
c = bytes.fromhex(ciphertext)
mode = DES3.MODE_CBC

for i in range(256):
    K3 = b'DASCTF{' + bytes([i])
    KEY = K1 + K2 + K3
    des3 = DES3.new(KEY, mode, IV)
    m = des3.decrypt(c)
    if b'CTF' in m:
        print(m)

# DASCTF{8e5ee461-f4e1-4af2-8632-c9d62f4dc073}

esyRSA

题目描述:

from gmpy2 import invert
from md5 import md5
from secret import p, q

e = ?????
n = p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
ans = gcd(e,phi)

print n, e, d
print "Flag: DASCTF{%s}" %md5(str(p + q)).hexdigest()

"""
n = 8064259277274639864655809758868795854117113170423331934498023294296505063511386001711751916634810056911517464467899780578338013011453082479880809823762824723657495915284790349150975180933698827382368698861967973964030509129133021116919437755292590841218316278732797712538885232908975173746394816520256585937380642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
"""

题目分析:

这题真的,没发现n重复了 这正常人哪想得到所给的n会出问题😔
步入正题
e ∗ d = 1 m o d    p h i ⇒ e ∗ d = 1 + k ∗ p h i ⇒ d p h i − k e = 1 e ∗ p h i p h i ≈ n , 且 p h i 非常大 ⇒ d n − k e = 1 e ∗ p h i 也就是说 d / n 与 k / d 非常接近,而 d / n 又已知 对 d / n 进行连分数展开,得到一串分数的分母很可能是 e 至此得到 k , e ⇒ p + q = n + 1 − ( e ∗ d − 1 ) / / k e * d = 1 \mod phi\\ \Rightarrow e * d = 1 + k * phi\\ \Rightarrow \frac{d}{phi} - \frac{k}{e} = \frac{1}{e * phi}\\ phi\approx n,且phi非常大\\ \Rightarrow \frac{d}{n} - \frac{k}{e} = \frac{1}{e * phi}\\ 也就是说d /n与k/d非常接近,而d/n又已知\\ 对d/n进行连分数展开,得到一串分数的分母很可能是e\\至此得到k,e\\ \Rightarrow p + q = n + 1 - (e * d - 1) // k ed=1modphied=1+kphiphidek=ephi1phin,phi非常大ndek=ephi1也就是说d/nk/d非常接近,而d/n又已知d/n进行连分数展开,得到一串分数的分母很可能是e至此得到k,ep+q=n+1(ed1)//k

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

n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913

c = continued_fraction(d/n)
for i in range(1, 500):
    k = int(c.numerator(i)) # 分子
    e = int(c.denominator(i))
    
    if (e * d - 1) % k==0:
        print(k)
        print(e)
        p_q = n + 1 - (e * d - 1) // k
        print('p + q =', p_q)
2384
13521
p + q = 18101966903197904104103274369549488558638013636328319260314053428770825687572755141919313812981523970938045930012152983362607947170555142776865084844865966

注意这一串,e为5位数,正好符合题目要求

# import hashlib
a = 18101966903197904104103274369549488558638013636328319260314053428770825687572755141919313812981523970938045930012152983362607947170555142776865084844865966
print(hashlib.md5(str(a).encode()).hexdigest())

# DASCTF{4ae33bea90f030bfddb7ac4d9222ef8f}

拓展:

连分数嘛,用维纳攻击代码也行,维纳攻击代码核心就在连分数这里,只要修改一下条件即可:

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

def continuedFra(x, y):
    cf = []
    while y:
        cf.append(x // y)
        x, y = y, x % y
    return cf

def gradualFra(cf):
    numerator = 0 # 分子
    denominator = 1 # 分母
    for x in cf[::-1]:
        # 这里的渐进分数分子分母要分开
        numerator, denominator = denominator, x * denominator + numerator
    return numerator, denominator

def getGradualFra(cf):
    gf = []
    for i in range(1, len(cf) + 1):
        gf.append(gradualFra(cf[:i]))
    return gf


def wienerAttack(d, n):
    cf = continuedFra(d, n)
    gf = getGradualFra(cf)
    for e,k in gf: # 不得不说最后要倒一下呀!
        if e == 1:
            continue
        if (e * d - 1) % k == 0:
            print(k)
            print(e)
            p_q = n + 1 - (e * d - 1) // k
            print('p + q =', p_q)

n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
a = wienerAttack(d,n)

所以说涉及连分数都可用维纳攻击代码,只需把条件稍微修改下,不过sage里面的continued_fraction()函数确实是更简洁

浅记一下

以上题目分析挺详细的吧哈哈
关键词:有限域开方(或AMM),格,私钥文件损坏,16位随机数预测机制,连分数,超递增

本次比赛只做出了前四道,题目难度中等,适合我这种小菜做。

SigninCrypto中的16位随机数预测机制我是真不知道,当时就困在K2,好难受,还是学的不扎实。esyRSA中的n重复了我也没发现,当时确实疑惑了,因为n分解出来好多数,会导致p或q不为素数,但之后也没多想了,唉。

现在细细想想,确实有问题,e * d = 1 % phi,不管e多大,d的数量级都会和phi差不多(也会和n差不多),然而此题中,相差巨大,两倍了,不合理,所以n有问题,事实也确实如此。唉,就这样吧,一起加油吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/968086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目——群英阁(galaxyHub)

目录 一、项目概述二、设计思路三、项目流程四、项目代码头文件&#xff1a;&#x1f447;server端&#xff1a;&#x1f447;client端&#xff1a;&#x1f447; 五、运行效果 一、项目概述 项目中文名称&#xff1a;群英阁 项目英文名称&#xff1a;galaxyHub 利用UDP通信实现…

HikariCP源码修改,使其连接池支持Kerberos认证

HikariCP-4.0.3 修改HikariCP源码,使其连接池支持Kerberos认证 修改后的Hikari源码地址:https://github.com/Raray-chuan/HikariCP-4.0.3 Springboot使用hikari连接池并进行Kerberos认证访问Impala的demo地址:https://github.com/Raray-chuan/springboot-kerberos-hikari-im…

Lambda表达式第三版,从3个方面分析。(①抽象方法无参数无返回值,②抽象方法带参数无返回值,③抽象方法带参数有返回值)

1、函数式编程思想概述 在数学中&#xff0c;函数就是有输入量、输出量的一套计算方案&#xff0c;也就是”拿数据做操作“面向对象思想强调”必须通过对象的形式来做事情“函数式思想则尽量忽略面向对象的复杂语法&#xff1a;”强调做什么&#xff0c;而不是以什么形式去做&a…

【javaweb】学习日记Day8 - Mybatis入门 Mysql 多表查询 事务 索引

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 【数据库原理与应用 - 第八章】数据库的事务管理与并发控制_一级封锁协议_Roye_ack的博客-CSDN博客 目录 一、多表查询 1、概述 &#xff08;1&#…

性能测试(测试系列10)

目录 前言&#xff1a; 1.什么是性能测试 1.1生活中遇到的软件问题 1.2性能测试的定义 1.3性能测试和功能测试有什么区别 1.4性能的好坏的区分 1.5影响一个软件性能的因素 2.为什么要进行性能测试 3.性能测试常见的术语以及衡量指标 3.1并发 3.2用户数 3.3响应时间 …

Jmeter如何设置中文版

第一步&#xff1a;找到 apache-jmeter-5.4.3\bin目录下的 jmeter.properties 第二步:打开 三&#xff0c;ctrf 输入languageen&#xff0c;注释掉&#xff0c;增加以行修改如下 四&#xff0c;ctrs 保存修改内容&#xff0c;重新打开jmeter就可以了

golang-bufio 缓冲写

1. 缓冲写 在阅读这篇博客之前&#xff0c;请先阅读上一篇&#xff1a;golang-bufio 缓冲读 // buffered output// Writer implements buffering for an io.Writer object. // If an error occurs writing to a Writer, no more data will be // accepted and all subsequent…

5.0: Dubbo服务导出源码解析

#Dubbo# 文章内容 Dubbo服务导出基本原理分析Dubbo服务注册流程源码分析Dubbo服务暴露流程源码分析服务导出的入口方法为ServiceBean.export(),此方法会调用ServiceConfig.export()方法,进行真正的服务导出。 1. 服务导出大概原理 服务导出的入口方法为ServiceBean.export…

stm32之28.ADC

须看原理图&#xff08;引脚、电压值、ADC几号通道&#xff09;配置 。 若对比值0~4096 模拟电压/参考电压4096/x 假设模拟电压2.1V&#xff0c;参考电压3.3v&#xff0c;4096/x3.3/2.1 ->3.3x2.1x4096 ->x2,606.5 也可反推出模拟电压 ADC转换时间 ADC时钟来源于…

leetcode645. 错误的集合(java)

错误的集合 题目描述优化空间代码演示 题目描述 难度 - 简单 LC645 - 错误的集合 集合 s 包含从 1 到 n 的整数。不幸的是&#xff0c;因为数据错误&#xff0c;导致集合里面某一个数字复制了成了集合里面的另外一个数字的值&#xff0c;导致集合 丢失了一个数字 并且 有一个数…

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测(风电功率预测)

时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测&#xff08;风电功率预测&#xff09; 目录 时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测&#xff08;风电功率预测&#xff09;预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.时序预测 | MA…

Python中的绝对和相对导入

在本文中&#xff0c;我们将看到Python中的绝对和相对导入。 Python中导入的工作 Python中的import类似于C/C中的#include header_file。Python模块可以通过使用import导入文件/函数来访问其他模块的代码。import语句是调用import机制的最常见方式&#xff0c;但它不是唯一的…

常见数学名词的物理意义(更新中)

BetterExplained – Math lessons that click 一、复数 i 的物理意义就是旋转&#xff0c;i 就是逆时针旋转90&#xff0c;i*i 就是逆时针旋转180 加法&#xff1a;实部相加&#xff0c;虚部相加 乘法&#xff1a; 复数zxyi控制了函数的放缩和旋转 ——x 放缩&#xff0c;…

Shell开发实践:服务器的磁盘、CPU、内存的占用监控

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

基于vue-cli创建后台管理系统前端页面——element-ui,axios,跨域配置,布局初步,导航栏

目录 引出安装npm install安装element-ui安装axios 进行配置main.js中引入添加jwt前端跨域配置 进行初始布局HomeView.vueApp.vue 新增页面和引入home页面导航栏总结 引出 1.vue-cli创建前端工程&#xff0c;安装element-ui&#xff0c;axios和配置&#xff1b; 2.前端跨域的配…

SQL查询本年每月的数据

--一、以一行数据的形式&#xff0c;显示本年的12月的数据&#xff0c;本示例以2017年为例&#xff0c;根据统计日期字段判断&#xff0c;计算总和&#xff0c;查询语句如下&#xff1a;selectsum(case when datepart(month,统计日期)1 then 支付金额 else 0 end) as 1月, sum…

UE4 春节鞭炮

先搞个基类&#xff0c;一个鞭炮的 搞个鞭炮类&#xff0c;存多个鞭炮 在构造函数的位置先生成对应的鞭炮数 将鞭炮绑定到绳子上&#xff0c;随绳子摆动而一起摆动 在基类里面写爆炸事件 最后用Timer去调用

一篇文章搞懂Redis缓存

目录 一、什么是缓存缓存的优缺点缓存的优点缓存的缺点 二、Redis缓存三、缓存的更新策略主动更新策略 四、缓存穿透解决方案 五、缓存雪崩解决方案 六、缓存击穿解决方案 一、什么是缓存 我们都知道在计算机中内存的速度比磁盘要快非常多&#xff0c;如果每次都要去磁盘获取数…

《Python魔法大冒险》004第一个魔法程序

在图书馆的一个安静的角落,魔法师和小鱼坐在一张巨大的桌子前。桌子上摆放着那台神秘的笔记本电脑。 魔法师: 小鱼,你已经学会了如何安装魔法解释器和代码编辑器。是时候开始编写你的第一个Python魔法程序了! 小鱼:(兴奋地两眼放光)我准备好了! 魔法师: 不用担心,…

Lesson6---案例:人脸案例

学习目标 了解opencv进行人脸检测的流程了解Haar特征分类器的内容 1 基础 我们使用机器学习的方法完成人脸检测&#xff0c;首先需要大量的正样本图像&#xff08;面部图像&#xff09;和负样本图像&#xff08;不含面部的图像&#xff09;来训练分类器。我们需要从其中提取特…