NSSCTF--Crypto--[强网拟态 2021]ONLYRSA
[强网拟态 2021]ONLYRSA
task:
#!/usr/bin/env python
from Crypto.Util.number import *
from secret import flag
n = 264048827496427248021277383801027180195275776366915828865010362454006394906519399441496561006668252031429735502465174250525698696973129422193405161920872162928097673289330345041221985548078586423910246601720647996170161319016119241836415788315729493164331517547663558380515400720081995290120793014108439083514403659082115510258023834737471488528527557960636984676435543300074504679264476413252780514962473070445293528877641502742438571110744667739728450283295649865745629276142949963507003094791773183928894536793857609738113546410753895719242547720815692998871947957214118354127328586542848234994500987288641595105
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print(c)
# 76196483810925191371357319946893762223027002702624516192769497540954799651198719100683206759706879828894501526423422596543748404479640715319801018211652987852179907519286760601944889601355220646374788026632971331786307898234821477134265724962397355614076896148563340833323366935479885600112872998594315513803419069126624158092821269145991266528158747750965226483644012365861166608598063649804899693010576080857540523307078138634628539419178875838147396170651777949577793359622498517581948006585916952705460782942977789615065947303447566918741750017127110484065354974088489869377128636357092420660532261674969708694
analysis:
这道RSA告诉我们的信息少之又少,我们能做的就是想尽办法分解n之后进行解密。
方法一:
# -*- coding: utf-8 -*-
# @Author : chen_xing
# @Time : 2024/12/16 上午11:59
# @File : [强网拟态 2021]ONLYRSA.py
# @Software: PyCharm
from Crypto.Util.number import *
# Given values
n = 264048827496427248021277383801027180195275776366915828865010362454006394906519399441496561006668252031429735502465174250525698696973129422193405161920872162928097673289330345041221985548078586423910246601720647996170161319016119241836415788315729493164331517547663558380515400720081995290120793014108439083514403659082115510258023834737471488528527557960636984676435543300074504679264476413252780514962473070445293528877641502742438571110744667739728450283295649865745629276142949963507003094791773183928894536793857609738113546410753895719242547720815692998871947957214118354127328586542848234994500987288641595105
c = 76196483810925191371357319946893762223027002702624516192769497540954799651198719100683206759706879828894501526423422596543748404479640715319801018211652987852179907519286760601944889601355220646374788026632971331786307898234821477134265724962397355614076896148563340833323366935479885600112872998594315513803419069126624158092821269145991266528158747750965226483644012365861166608598063649804899693010576080857540523307078138634628539419178875838147396170651777949577793359622498517581948006585916952705460782942977789615065947303447566918741750017127110484065354974088489869377128636357092420660532261674969708694
# factor
primes = [5,29,31,197,12541,4811988280952344246576937,304081130082418831034791698146581643331044047712028910273173568327362370621651464924047927850720915897334538205155796477275515888954493777509372421863858817079340724222044305450451984754173948523380921443850440010226012354226083642718433164324022575599948330147718863789069,16249579302136675275737472669394168521026727339712083110552530420348131906271518040549529167354613121510156841352658645018277766962773342379074137176993546193979134201416444089373463960664685121485689105129185197998903479181913613273443541075619342246119648308939006396145123630152777688592984718084919469059]
print("--------------------------------------------------begin--------------------------------------------------")
phi = 1
for prime in primes:
if isPrime(prime):
phi *= prime - 1
else:
print("Factor error!")
n //= prime
print(long_to_bytes(pow(c,inverse(65537,phi),n)))
print("---------------------------------------------------end---------------------------------------------------")
# b'flag{5c066086-178b-46a7-b0f8-f1afba6f2910}'
方法二:
前备知识:
a.digits(b)
函数是对于sagemath中Integer
类型的处理方法,接受两个参数a
,b
将a
转化为b
进制之下的结果之后每一位都储存在列表中(逆序),例如:
print(150.digits())
# [0,5,1]
R.<x> = PolynomialRing(ZZ)
可以创建一个以整数环 ZZ
为系数的多项式环,变量为 x
。
f = R(a)
:将 a
列表作为多项式的系数列表,生成一个多项式。例如,如果 a = [1, 2, 3]
,生成的多项式将是 1 + 2x + 3x^2
。
factor(f)
语句可以对f进行整数域上的因式分解,因式分解后的式子是含有x变量的多项式,带入x后就可以得到分解后的值。
这里根据题目October -> December对应十进制 -> 11进制。
转成11进制之后发现稀疏(项数少)。然后就是把11进制看成一个多项式,在多项式环上进行分解,分成两个大多项式相乘,然后再代回11。
exp:
# sagemath
n = 264048827496427248021277383801027180195275776366915828865010362454006394906519399441496561006668252031429735502465174250525698696973129422193405161920872162928097673289330345041221985548078586423910246601720647996170161319016119241836415788315729493164331517547663558380515400720081995290120793014108439083514403659082115510258023834737471488528527557960636984676435543300074504679264476413252780514962473070445293528877641502742438571110744667739728450283295649865745629276142949963507003094791773183928894536793857609738113546410753895719242547720815692998871947957214118354127328586542848234994500987288641595105
e = 65537
c = 76196483810925191371357319946893762223027002702624516192769497540954799651198719100683206759706879828894501526423422596543748404479640715319801018211652987852179907519286760601944889601355220646374788026632971331786307898234821477134265724962397355614076896148563340833323366935479885600112872998594315513803419069126624158092821269145991266528158747750965226483644012365861166608598063649804899693010576080857540523307078138634628539419178875838147396170651777949577793359622498517581948006585916952705460782942977789615065947303447566918741750017127110484065354974088489869377128636357092420660532261674969708694
n_eleven_list = n.digits(11)
R.<x> = PolynomialRing(ZZ)
f = R(n_eleven_list)
factors = f.factor()
p = factors[0][0]
q = factors[1][0]
p = p(x = 11)
q = q(x = 11)
print(f"p = {p}")
print(f"q = {q}")
# -*- coding: utf-8 -*-
# @Author : chen_xing
# @Time : 2024/12/16 上午11:59
# @File : [强网拟态 2021]ONLYRSA.py
# @Software: PyCharm
from Crypto.Util.number import *
# Given values
n = 264048827496427248021277383801027180195275776366915828865010362454006394906519399441496561006668252031429735502465174250525698696973129422193405161920872162928097673289330345041221985548078586423910246601720647996170161319016119241836415788315729493164331517547663558380515400720081995290120793014108439083514403659082115510258023834737471488528527557960636984676435543300074504679264476413252780514962473070445293528877641502742438571110744667739728450283295649865745629276142949963507003094791773183928894536793857609738113546410753895719242547720815692998871947957214118354127328586542848234994500987288641595105
c = 76196483810925191371357319946893762223027002702624516192769497540954799651198719100683206759706879828894501526423422596543748404479640715319801018211652987852179907519286760601944889601355220646374788026632971331786307898234821477134265724962397355614076896148563340833323366935479885600112872998594315513803419069126624158092821269145991266528158747750965226483644012365861166608598063649804899693010576080857540523307078138634628539419178875838147396170651777949577793359622498517581948006585916952705460782942977789615065947303447566918741750017127110484065354974088489869377128636357092420660532261674969708694
p = 16249579302136589695295481114504339262045249125801939374419304404565893699789462299636475519992076209810443523832755415818528536943125532985768629325734679453205207122927745917471850395124342956866284689792620888965652429711989205344392333681297321070276796015579775171010928476523589349812683875326849195595
q = 16249579302136675275737472669394168521026727339712083110552530420348131906271518040549529167354613121510156841352658645018277766962773342379074137176993546193979134201416444089373463960664685121485689105129185197998903479181913613273443541075619342246119648308939006396145123630152777688592984718084919469059
print("--------------------------------------------------begin--------------------------------------------------")
assert p * q == n
if isPrime(p) and isPrime(q):
print(long_to_bytes(pow(c,inverse(65537,(p-1)*(q-1)),n)))
elif isPrime(p):
print(long_to_bytes(pow(c,inverse(65537,p-1),p)))
else:
print(long_to_bytes(pow(c,inverse(65537,q-1),q)))
print("---------------------------------------------------end---------------------------------------------------")