CTF Crypto --- essential

文章讲述了使用Python的sympy库找到两个素数p和q,它们分别位于给定素数a的13倍和25倍附近。接着,利用gmpy2库进行素数判断和RSA加密解密,解密给定的加密值c1和c2,最终得到flag。解题过程涉及到了对数的平方根、模逆运算等数学概念。
摘要由CSDN通过智能技术生成

题目

from Crypto.Util.number import *
import sympy
from flag import flag
a=getPrime(512)
p=sympy.nextprime(13*a)
q=sympy.prevprime(25*a)
number2=p*q

def crypto01(number1, number2, number3):
    number4 = 1
    while number2 > 0:
        if number2 % 2: 
            number4 = (number4 * number1) % number3
        number1 = number1 ** 2 % number3
        number2 //= 2
    return number4

def crypto02(number1, number2):
    number3 = number1
    number4 = number2
    giao = 1
    giaogiao = 0
    while number4 > 0:
        number7 = number3 // number4
        giao, giaogiao = giaogiao, giao - giaogiao*number7
        number3, number4 = number4, number3 - number4*number7
    while giao<0:
        giao = giao + number2
    return giao

def crypto03(number1, number2, number3):
    number4 = crypto01(number3, number1, number2)
    return number4



def crypto05(number1,number2):
    return pow(number1,0xe18e,number2)






number1 = 6035830951309638186877554194461701691293718312181839424149825035972373443231514869488117139554688905904333169357086297500189578624512573983935412622898726797379658795547168254487169419193859102095920229216279737921183786260128443133977458414094572688077140538467216150378641116223616640713960883880973572260683
number2 = 20163906788220322201451577848491140709934459544530540491496316478863216041602438391240885798072944983762763612154204258364582429930908603435291338810293235475910630277814171079127000082991765275778402968190793371421104016122994314171387648385459262396767639666659583363742368765758097301899441819527512879933947

number3 = int.from_bytes(flag[0:19].encode("utf-8"), "big")
number4 = int.from_bytes(flag[19:39].encode("utf-8"), "big")

print(crypto03(number1, number2, number3))
print(crypto05(number4,number2))
#6624758244437183700228793390575387439910775985543869953485120951825790403986028668723069396276896827302706342862776605008038149721097476152863529945095435498809442643082504012461883786296234960634593997098236558840899107452647003306820097771301898479134315680273315445282673421302058215601162967617943836306076
#204384474875628990804496315735508023717499220909413449050868658084284187670628949761107184746708810539920536825856744947995442111688188562682921193868294477052992835394998910706435735040133361347697720913541458302074252626700854595868437809272878960638744881154520946183933043843588964174947340240510756356766

解题过程

a是一个512bit的素数,而 p = s y m p y . n e x t p r i m e ( 13 ∗ a ) , q = s y m p y . p r e v p r i m e ( 25 ∗ a ) p = sympy.nextprime(13*a),q=sympy.prevprime(25*a) p=sympy.nextprime(13a),q=sympy.prevprime(25a)
p 是 13 ∗ a 的下一个素数, q 是 25 ∗ a 的前一个素数 p是13*a的下一个素数,q是25*a的前一个素数 p13a的下一个素数,q25a的前一个素数
按照相邻素数定律,连续两个素数不超过1500
可得, n ≈ 13 ∗ 25 ∗ a 2 n \approx 13*25*a^2 n1325a2
因此,我们对 n 25 ∗ 13 \frac{n}{25*13} 2513n开平方,可以得到一个接近a的数。然后我们循环取 n e a r − a near-a neara的下一个素数直到被n整除为止,此时a为所求,进而求得p和q。由于e = 57742,是一个偶数,所以后面是一个e和phi不互素问题,简单处理一下即可得到flag2。

a_near = gmpy2.iroot(number2//325,2)[0]
while number2 % gmpy2.next_prime(13*a_near)!=0:
    a_near = gmpy2.next_prime(a_near)
p = gmpy2.next_prime(13*a_near)
q = number2//p

接下来主要是对于加密函数crypto1的理解

def crypto01(number1, number2, number3):
    number4 = 1
    while number2 > 0:
        if number2 % 2: 
            number4 = (number4 * number1) % number3
        number1 = number1 ** 2 % number3
        number2 //= 2
    return number4

阅读代码可知,当number2为奇数时,number4 = (number4 * number1) % number3。number2 //= 2,那么number2会以奇数和偶数的方式交替存在直至number2小于0,在交替过程中,只有为奇数时才会乘以number1,但是为偶数的时候number1等于number1**2 % number3;也就是说,每一次乘以number1的时候,实际上是乘以了number1**2 mod number3 。ok,到这里就很清晰了,这个加密函数实际上是pow(number1,number2,number3)函数,接下来就是简单RSA解密计算出flag1

解题代码

#!python3
# -*- coding: utf-8 -*-
# @Time    : 2023/7/19 14:57
# @Author  : 3tefanie丶zhou
# @FileName: essential_exp.py
from Crypto.Util.number import *
import gmpy2

number1 = 6035830951309638186877554194461701691293718312181839424149825035972373443231514869488117139554688905904333169357086297500189578624512573983935412622898726797379658795547168254487169419193859102095920229216279737921183786260128443133977458414094572688077140538467216150378641116223616640713960883880973572260683
number2 = 20163906788220322201451577848491140709934459544530540491496316478863216041602438391240885798072944983762763612154204258364582429930908603435291338810293235475910630277814171079127000082991765275778402968190793371421104016122994314171387648385459262396767639666659583363742368765758097301899441819527512879933947
c1 = 6624758244437183700228793390575387439910775985543869953485120951825790403986028668723069396276896827302706342862776605008038149721097476152863529945095435498809442643082504012461883786296234960634593997098236558840899107452647003306820097771301898479134315680273315445282673421302058215601162967617943836306076
c2 = 204384474875628990804496315735508023717499220909413449050868658084284187670628949761107184746708810539920536825856744947995442111688188562682921193868294477052992835394998910706435735040133361347697720913541458302074252626700854595868437809272878960638744881154520946183933043843588964174947340240510756356766
e = 57742
# solve flag2
a_near = gmpy2.iroot(number2//325,2)[0]
while number2 % gmpy2.next_prime(13*a_near)!=0:
    a_near = gmpy2.next_prime(a_near)
p = gmpy2.next_prime(13*a_near)
q = number2//p
phi = (p-1)*(q-1)
t = gmpy2.gcd(e,phi)
d = gmpy2.invert(e//t,phi)
m2 = gmpy2.iroot(pow(c2,d,number2),t)[0]
flag2 = long_to_bytes(m2)
# solve flag1
d1 = gmpy2.invert(number1,phi)
m1 = pow(c1,d1,number2)
flag1 = long_to_bytes(m1)
print(flag1+flag2)

flag:

flag{75811c6d95770d56092817b75f15df05}

【城头小陌未逢春,不见梅花不见人。】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值