[NKCTF 2024] crypto 部分

文章目录

ez_math

题目描述:

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

m1, m2 = bytes_to_long(flag[:len(flag)//2]), bytes_to_long(flag[len(flag)//2:])
p, q, r, s = [getStrongPrime(512) for _ in range(4)]
e = 0x10001

n = p * q * r * s
x = pow(q + r, p, n)
y = pow(p * q + r, p, n)
z = pow(s + 1, m1, s ** 3)
c = pow(m2, e * (s - 1), n)

print(f'{n = }')
print(f'{x = }')
print(f'{y = }')
print(f'{z = }')
print(f'{c = }')

# n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
# x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
# y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
# z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
# c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870

题目分析:
part1:
x ≡ ( q + r ) p ( m o d n ) ≡ r p ( m o d q ) ① ≡ ( q + r ) ( m o d p ) ② y ≡ ( p q + r ) p ( m o d n ) ≡ r p ( m o d q ) ③ ≡ ( p q + r ) ( m o d p ) ④ ≡ r ( m o d p ) ⑤ z ≡ ( s + 1 ) m 1 ( m o d s 3 ) ≡ ( m 1 − 1 ) ∗ m 1 2 ∗ s 2 + m 1 ∗ s + 1 ( m o d s 3 ) ≡ m 1 ∗ s + 1 ( m o d s 2 ) ⑥ \begin{align*} x &\equiv (q + r)^p \pmod n \\ &\equiv r^p \pmod q ①\\ &\equiv (q + r) \pmod p ②\\ y &\equiv (pq + r)^p \pmod n \\ &\equiv r^p \pmod q ③\\ &\equiv (pq + r) \pmod p④\\ &\equiv r \pmod p⑤\\ z &\equiv(s + 1)^{m_1} \pmod {s^3}\\ &\equiv \frac{(m_1 - 1) * m_1}{2} * s^2 + m_1 * s + 1 \pmod {s^3}\\ &\equiv m_1 * s + 1 \pmod {s^2}⑥ \end{align*} xyz(q+r)p(modn)rp(modq)(q+r)(modp)(pq+r)p(modn)rp(modq)(pq+r)(modp)r(modp)(s+1)m1(mods3)2(m11)m1s2+m1s+1(mods3)m1s+1(mods2)
n = p ∗ q ∗ r ∗ s 由①③知 q = g c d ( x − y , n ) 由②④知 x − y = p q − q + k p , x − y + q = p q + k p ⇒ p q = g c d ( x − y + q , n ) p , q 出来了再由⑤得到 r 至此得到 s ,进而通过⑥得到 m 1 n = p * q * r * s\\ 由①③知q = gcd(x - y,n)\\ 由②④知x-y = pq - q + kp,x-y + q = pq + kp\\ \Rightarrow pq = gcd(x - y + q, n)\\ p,q出来了再由⑤得到r\\ 至此得到s,进而通过⑥得到m_1 n=pqrs①③q=gcd(xy,n)②④xy=pqq+kpxy+q=pq+kppq=gcd(xy+q,n)pq出来了再由得到r至此得到s,进而通过得到m1

q = gcd(x - y, n)
p = gcd((x - y - q),n) // q
r = y % p
s = n // (p * q * r)
print(s)
m1_s = z % s ** 2
print(long_to_bytes(m1_s//s)) # nkctf{cb5b7392-cca4-4 # 21 * 8 = 168

part2:
c 2 = p o w ( m 2 , e ∗ ( s − 1 ) , n ) c_2 = pow(m_2,e * (s - 1),n) c2=pow(m2,e(s1),n)
不互素问题,不过此时与phi的公因子是s - 1,太大了,那我们缩小范围
c 2 = p o w ( m 2 , e ∗ ( s − 1 ) , p q r ) c_2 = pow(m_2,e * (s - 1),pqr) c2=pow(m2,e(s1),pqr)
发现 g c d ( e ∗ ( s − 1 ) , ( p − 1 ) ∗ ( q − 1 ) ∗ ( r − 1 ) ) = 4 发现gcd(e * (s - 1),(p - 1) * (q - 1) * (r - 1)) = 4 发现gcd(e(s1)(p1)(q1)(r1))=4
这个公因子小,有限域开方就行,之后得到 f l a g 这个公因子小,有限域开方就行,之后得到flag 这个公因子小,有限域开方就行,之后得到flag

exp:

from gmpy2 import *
from Crypto.Util.number import *
n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870
q = gcd(x - y, n)
p = gcd((x - y - q),n) // q
r = y % p
s = n // (p * q * r)
m1_s = z % s ** 2
print(long_to_bytes(m1_s//s)) # nkctf{cb5b7392-cca4-4 # 21 * 8 = 168
phi = (p - 1) * (q - 1) * (r - 1)
# d = inverse(e * (s - 1) // 4,phi)
d = 10292015846226326626370949985893948454242815204536321567714079741863425644546741087742200394303759750805247274743208392548576973216333023868386336877699087761327762194552911961182361711805502363445273786531387634353279385813410433183027148735707050395036809376879910491222740252472008020497921316703002861855586695106995399872988828440326885200014455341405642060722665755794358954331817810279743968806464910408348141541467067267342883947498952304516890032676283
m_4 = pow(c,d,p * q * r)
e = 4
R.<x> = Zmod(p)[]
f=x^e-m_4
mps=f.monic().roots()

for i in mps:
    flag=long_to_bytes(int(i[0]))
    if b'}' in flag:
        print(flag) 
# ce2-87e7-930cf6b29959}

GGH

题目描述:

from sage.all import *
from flag import flag,n,delta # 格的维数,错误向量的最大范数
def hadamard_ratio(basis): # 计算哈达玛比率
    dimension = basis.nrows() # 获取基(basis)的行数,也就是基的维度
    det_Lattice = det(basis) # 计算基的行列式值
    mult=1.0
    for v in basis:
        mult *= float(v.norm(2)) # 计算每个向量 v 的2-范数(Euclidean norm),并将其乘以 mult
    hratio = (det_Lattice / mult) ** (1/dimension) # 计算哈达玛比率
    return hratio
def get_key(n): # 生成一个哈达玛比率大于0.86的格,并返回原始格 V 和密钥格 W
    l = 7
    k = ceil(sqrt(n) + 1) * l # 7 * n ** 0.5
    I = identity_matrix(n) # 单位矩阵
    while 1:
        V_ = random_matrix(ZZ,n, n, x=-l, y=l) # n * n的矩阵,其中最小值为-1,最大值为1
        V = V_ + I * k # 随机矩阵的主对角线上每个元素都加上 7 * n ** 0.5
        hada_ratio = hadamard_ratio(V) # 计算矩阵V的哈达玛比率 # 好基
        if hada_ratio > 0.86:
            # 用于生成模不变(unimodular)矩阵的函数。模不变矩阵是一个行列式的绝对值为1的整数矩阵
            U = unimodular_matrix(n) 
            W = V * U
            return V, W
        else:
            continue

def unimodular_matrix(n): # 模不变矩阵
    S = identity_matrix(n) 
    X = identity_matrix(n) 
    for i in range(n):
        for j in range(i,n):
            S[j, i] = choice([-1,1]) # 下三角填充随机的-1或1
            X[i, j] = choice([-1,1]) # 上三角填充随机的-1或1
    assert  det(S*X) == 1 or det(S*X) == -1
    return S*X # 一些特别小的向量
# n = 260
def get_error(n,delta): # 生成错误向量,delta = [0,20]
    k = 4*delta -2 
    tmp = [] 
    tmp += [delta - 2]*(n//k) 
    tmp += [delta - 1]*( ((k-2)*n) // (2*k)) 
    tmp += [delta]*(n//k) 
    tmp += [delta + 1]*( ((k-2)*n) // (2*k)) #
    return tmp

assert len(flag) == 44
assert delta < 20 

V,W = get_key(n) 
gift = str(hex(randint(70, 80))).zfill(5).encode('utf-8')
flag =  gift + flag
print(flag)
m = [i for i in flag]
pad = [randint(-128, 127) for i in range(n-len(m)) ]
m = vector(ZZ, m + pad)
r = vector(get_error(n,delta))
c = m * W + r
# 这里 (r).norm() 表示向量 r 的范数(norm)
assert floor((r).norm()) == delta*(floor(sqrt(n)))

with open('pubkey.txt', 'w') as f:
    f.write(str(W))

with open('ciphertext.txt', 'w') as f:
    f.write(str(c))

题目分析:
c = m * W + r
m * W = c - r
W,c均已知,那直接爆破r得到m

import numpy as np
with open('ciphertext.txt') as f:
    exec(f.read())
    
n = 260
B = []
with open('pubkey.txt', 'r') as file:
    content = file.readlines()
for line in content:
    line_data = [int(num) for num in line.strip('[] \n').split()]
    B.append(line_data)
    
W = matrix(ZZ, B)

tt = []
for delta in range(2,20):
    k = 4*delta -2
    tmp = [] 
    tmp += [delta - 2]*(n//k)
    tmp += [delta - 1]*( ((k-2)*n) // (2*k))
    tmp += [delta]*(n//k)
    tmp += [delta + 1]*( ((k-2)*n) // (2*k))
    if len(tmp) != 260:
        continue
    cc = list(c - t for c,t in zip(c,tmp))
    C = matrix(ZZ,cc)
    m = W.solve_left(C).list()
    for i in m:
        if i[0] == 48:
            print(m)
            break
            
m = [48, 48, 120, 52, 100, 110, 107, 99, 116, 102, 123, 71, 48, 111, 100, 95, 89, 48, 117, 95, 65, 114, 51, 95, 75, 110, 48, 87, 95, 71, 103, 104, 95, 67, 114, 121, 112, 116, 48, 115, 121, 115, 116, 51, 109, 33, 33, 33, 125, 8, -109, -119, 103, -1, 17, -88, -63, 85, 100, -21, 74, -70, 21, -78, 101, 75, 3, 7, -80, 22, 101, 6, -105, 69, 32, -76, 86, -25, 58, 89, 1, -37, -19, 53, 42, 76, -67, 14, -88, 95, -48, -120, -109, -47, -9, 36, 5, 59, -83, -8, -27, -57, 122, 0, -88, 70, 60, 2, -84, -69, -91, -71, 28, 2, 52, 125, 55, -96, -114, 126, 18, 64, 82, 109, -104, -84, -114, -1, 7, 7, 87, -111, -120, 121, -49, 115, 28, 9, 12, 21, -65, 27, -51, 106, 109, 96, 32, -80, 52, -91, 41, -103, -32, -112, 59, 71, 74, 99, 78, 103, -101, 46, -43, -16, 88, 62, 12, -91, -3, 40, 118, -112, -80, -94, -19, 40, -50, -60, 10, -96, 68, 58, 99, -100, -33, 63, 79, 103, -83, -2, 111, 3, -20, 75, 93, 20, 35, -32, -73, -67, -48, -92, -103, -7, -121, -124, -71, -11, -21, -55, -31, -124, 22, 122, 70, -115, 108, 92, 104, -104, -4, -53, 1, 103, 123, -123, -92, 49, 122, -47, 120, -122, -81, -116, 56, 64, -125, -96, -24, -116, 80, -108, 114, 107, -101, -8, 0, 115, 45, 6, -42, 15, -56, 122, -95, -97, -35, -93, 75, -91]
for i in m:
    print(chr(int(m)),end = '')
# nkctf{G0od_Y0u_Ar3_Kn0W_Ggh_Crypt0syst3m!!!}

官方wp看了一下,另一种解法,等会有时间就都去复现一下(目前好像还抽不出时间 唉)

  • 13
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js 中的 crypto 是一个内置模块,用于提供加密和解密功能。它支持各种加密算法和操作,包括哈希函数、对称加密和非对称加密。你可以使用 crypto 模块来实现数据的加密、解密、签名和验证等操作。 要使用 crypto 模块,你需要在你的代码中引入它,例如: ```javascript const crypto = require('crypto'); ``` 一些常见的 crypto 操作包括: 1. 哈希函数:crypto 模块提供了多个哈希函数,如 MD5、SHA-1、SHA-256 等。你可以使用这些函数对数据进行哈希处理,生成唯一的摘要。例如: ```javascript const hash = crypto.createHash('sha256'); hash.update('Hello, world!'); const digest = hash.digest('hex'); console.log(digest); // 输出生成的摘要 ``` 2. 对称加密:crypto 模块支持对称加密算法,如 AES、DES、3DES 等。你可以使用这些算法对数据进行加密和解密。例如: ```javascript const cipher = crypto.createCipher('aes192', 'password'); let encrypted = cipher.update('Hello, world!', 'utf8', 'hex'); encrypted += cipher.final('hex'); console.log(encrypted); // 输出加密后的数据 const decipher = crypto.createDecipher('aes192', 'password'); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); console.log(decrypted); // 输出解密后的数据 ``` 3. 非对称加密:crypto 模块还支持非对称加密算法,如 RSA。你可以使用这些算法生成公钥和私钥,进行加密和解密。例如: ```javascript const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 4096, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); console.log(publicKey); // 输出生成的公钥 console.log(privateKey); // 输出生成的私钥 const encrypted = crypto.publicEncrypt(publicKey, Buffer.from('Hello, world!')); console.log(encrypted.toString('base64')); // 输出加密后的数据 const decrypted = crypto.privateDecrypt(privateKey, encrypted); console.log(decrypted.toString('utf8')); // 输出解密后的数据 ``` 这只是 crypto 模块的一小部分功能,你可以查阅 Node.js 文档以获取更详细的信息和使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值