题目
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(13∗a),q=sympy.prevprime(25∗a)
p
是
13
∗
a
的下一个素数,
q
是
25
∗
a
的前一个素数
p是13*a的下一个素数,q是25*a的前一个素数
p是13∗a的下一个素数,q是25∗a的前一个素数
按照相邻素数定律,连续两个素数不超过1500
可得,
n
≈
13
∗
25
∗
a
2
n \approx 13*25*a^2
n≈13∗25∗a2
因此,我们对
n
25
∗
13
\frac{n}{25*13}
25∗13n开平方,可以得到一个接近a的数。然后我们循环取
n
e
a
r
−
a
near-a
near−a的下一个素数直到被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}
【城头小陌未逢春,不见梅花不见人。】