UUCTF CRYPTO 官方WriteUP

前言

第一次受邀给比赛出密码学的题目,本人也不是很会密码学,出的题质量都不是很好,给各位师傅道个歉qwq

爱丽丝梦境的兔子

下载附件看到了一段编码后的文本, 结合题目描述直接梭

兔子是指Rabbit编码,有在线网站可以解

然后就是社会主义核心价值观编码,同样用在线网站解

随后的跳过6排栅栏就是指栏数为6的栅栏密码了,直接在线网站解一下得到flag

flag{W3lc0me_to_tys3C!}

disparity_rsa

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

n = getPrime(16) * getPrime(1024)
e = 65537
c = pow(libnum.s2n(flag), e, n)
print(n)
print(c)
"""
5766276392358749678465293140086098467966750231712371312128357014391999737216038752230724284342592823121355823795866483203180931048954335112770774107559486755364212210458976151334722695492171477074797849017986146274077476865962084775522903856595231226401087381140264069846311320790344977681853590320235273290951697
2045715881946911272235143200802867525029545408884378407157206152052553006168468197781701884100551265225998396305370344041310549543210998337911706435156837312343915033047602409702498958543942876869008345155456133353563984395357862622021564371486943574405858053628504628093173853945529577974028398631861979247502108s
"""

观察一下题目代码,发现n的生成过程并不安全

n = getPrime(16) * getPrime(1024)

由于n的一个素因子过小,会造成直接模数分解,使用yafu秒出n的两个素因子

然后就是常规RSA解密了,放一波脚本

from Crypto.Util.number import long_to_bytes
import gmpy2
p = 57191
q = 100824891894856702601201118009583648965164977561371042858637845367138181483380929730739526924561431398670347148954669147299066829552802628259180187574259704417901631558444093499584247442642574479809722666468258052387219612630695122930581802321960294913554359621973108878080665153439264529066699136581547328967
e = 65537
n = p * q
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e,phi)
c = 2045715881946911272235143200802867525029545408884378407157206152052553006168468197781701884100551265225998396305370344041310549543210998337911706435156837312343915033047602409702498958543942876869008345155456133353563984395357862622021564371486943574405858053628504628093173853945529577974028398631861979247502108
print(long_to_bytes(pow(c,d,n)))
#b'flag{great!_Y0u_s0lve_m9_challenge!}'

Easy_base64

from flag import flag
import base64
assert flag[0:4] == "flag"
tmp=base64.b64encode(bytes(flag,"utf-8"))
flag=str(tmp)[2:-1]
for i in range(0,len(flag)-1):
    print(ord(flag[i]) ^ ord(flag[i+1]),end=" ")
#55 21 16 50 105 71 14 27 41 30 34 16 50 111 74 62 5 18 54 52 106 85 31 54 24 111 83 11 38 1 53 17 37 17 35 47 32 52 40 2 9 59 47 54 25 111 77 16 48 26 33 9 55 108 0

观察题目源码,发现是先将flag进行了base64加密,然后将第i个字符转换为ascii后异或第i+1个字符的ascii
这里我们可以使用异或的性质来还原flag

A ^ B ^ B = A

知道思路以后就是纯脚本编写题了,flag经base64编码后第一个字母为"Z",用python写个for循环异或回去即可

import base64

list = [55 ,21 ,16, 50 ,105 ,71, 14, 27 ,41 ,30, 34 ,16, 50, 111 ,74 ,62, 5 ,18 ,54, 52, 106,85 ,31, 54 ,24, 111, 83, 11, 38, 1, 53, 17, 37, 17, 35, 47, 32, 52, 40, 2, 9, 59, 47, 54, 25, 111, 77, 16, 48, 26, 33, 9, 55, 108, 0]
flag = "Z"
for i in range(len(list)):
    flag += chr(ord(flag[i])^list[i])
print(base64.b64decode(flag))
#b'flag{shumu_l0ve_h15_challeng3_ver9_mu3h}'

unsafe_prime

这道题一开始甚至上错了附件,但是题目并不难,所以最后解出还是很高的(

from Crypto.Util.number import *
from flag import flag
import libnum
p=getPrime(1024)
n=p**3
e=65537
c=pow(libnum.s2n(flag),e,n)
print(n)
print(c)
#1781066779141074297846071955037887396311182371062305797790413639302252321886055189043670187843106208315282055227397316083218930657040969292641990094428330517286511511741846106485971830443788363541411679523274683568732340113625424593194464460018629545968907529693143364870519531630721083893407011154181539445417439610805148961135948617691115328261432541033785402520757881586489819563221498111411690769065511011083021336493731421274742041131952523427183184133413677315203810963447656037908287875212013900845740870561508870574734100843624059414134156975073835607712519402938132401964708681236647568922173471703538744207491065165405594141287750705055447493380970194312139898574699147098202027540057477562090764694370368571887563631557761911842054442637038169316686266784299889397326811768646649462480349219937292894824766045607723468654723947999531346474969019631500665628522355198334827965770037487344994396753505248472283247731
#1402371150275079475353867962992356093684205278224746766691813462864343871795075217989508355749642716635931824907174189358797217546624305634264458802157933311315419673854405865092102322247505412453586251582022669511221048298234732642016439123525455296325766292112758881774720932499142635136210314142144509741404827421282969081272484330382868174392651681290127032351489627054643864671335712011990584326951285867375878235135547391155357814807654366986019707719726796289990920154227959213228064918435259919697047405788311280560319520593639968900649500117511665741073545430999580686455996145426173603547052710181735901020361145546892741579951501409108067297139928103329203429485237575169217432586580425019729120741661192297552519858305628835738911159460615968385837687234565509200392302553443089729906970894661310333276852803980265040679214814192141779678148895736682538612828771031493541256243879854624644771924477873876038496224

观察代码,发现n= p 3 p^3 p3,那么我们就可以求出 n 3 \sqrt[3]{n} 3n 来得到p,然后进行常规的RSA解密,下面放出脚本

import gmpy2
from Crypto.Util.number import *
n = 1781066779141074297846071955037887396311182371062305797790413639302252321886055189043670187843106208315282055227397316083218930657040969292641990094428330517286511511741846106485971830443788363541411679523274683568732340113625424593194464460018629545968907529693143364870519531630721083893407011154181539445417439610805148961135948617691115328261432541033785402520757881586489819563221498111411690769065511011083021336493731421274742041131952523427183184133413677315203810963447656037908287875212013900845740870561508870574734100843624059414134156975073835607712519402938132401964708681236647568922173471703538744207491065165405594141287750705055447493380970194312139898574699147098202027540057477562090764694370368571887563631557761911842054442637038169316686266784299889397326811768646649462480349219937292894824766045607723468654723947999531346474969019631500665628522355198334827965770037487344994396753505248472283247731
c = 1402371150275079475353867962992356093684205278224746766691813462864343871795075217989508355749642716635931824907174189358797217546624305634264458802157933311315419673854405865092102322247505412453586251582022669511221048298234732642016439123525455296325766292112758881774720932499142635136210314142144509741404827421282969081272484330382868174392651681290127032351489627054643864671335712011990584326951285867375878235135547391155357814807654366986019707719726796289990920154227959213228064918435259919697047405788311280560319520593639968900649500117511665741073545430999580686455996145426173603547052710181735901020361145546892741579951501409108067297139928103329203429485237575169217432586580425019729120741661192297552519858305628835738911159460615968385837687234565509200392302553443089729906970894661310333276852803980265040679214814192141779678148895736682538612828771031493541256243879854624644771924477873876038496224
e = 65537
p = gmpy2.iroot(n,3)[0]
phi = p-1
d = gmpy2.invert(e,phi)
m = pow(c,d,p)
print(long_to_bytes(m))
#b'flag{Shumu_th1nk_saf3_pr1me_ar3_importanT!}'

Impossible_RSA

这道题相对来说难度大很多,但是也并非题目名称中的impossible

import libnum
from Crypto.Util.number import getPrime
from flag import flag, e

p = getPrime(1024)
q = getPrime(1024)
n = p * q
assert e <= 500000
c = pow(libnum.s2n(flag), e, n)
leak1 = c % q
leak2 = c % p
leak3 = p + q
print("n =", n)
print("leak1 =", leak1)
print("leak2 =", leak2)
print("leak3 =", leak3)

"""
n = 21256406304024147327122699985764737895162788854942201173538004689536569610046157311527715126074775927977409773971656249943602454790380966869525211733301201659688694473703188427037879868522859419364680904585572399937639393418586498509580133474303442722716959873727260844993296681950092753897902540593927952622713860163782763263944291810729056735965535138964485886748344167499818148134252327820007439830749462775149754781930983094046362696040641091039506998835624218220892441813224657845627120344960554424765109502415773475619490661527184126374299883610442465428985757004551740482644952396990065188807827114495184096249
leak1 = 8842431959638543756327530752221031675897458993985909403335303147413741167900365489182674478419510549838159493192002672500346433589707076289344572454304647803237654059883974235710442126617587691632375039292283285577033977676131772115877520248352227419433136507412485140428972344000541898060766721412300525883
leak2 = 127414092867622693231378230621806169422569654246682818498761930473755998913688181327473434110121174292309611256339271412324673262030535400937563769685033472683498585742711576446343086462569783541192470920638935990937187809422965809986860709074542257475025562691683977493260026623616012846939417988284096473040
leak3 = 293130152177150437492580785085598394773458388719469800871702200331766258900690595210759869625006484354799804558552583572062231998451041105464048317708732987121458633718573774164071597186461239762511364549980544029915308083867329707804739776241438307060614946195675715671343671137725809499387682363101164970886
"""

我们观察题目,发现n=p*q且leak3=p+q,那么我们就可以列一个二元一次方程组从而求出p和q了
这里我们使用sage求p和q,那样非常easy

#sage
n = 21256406304024147327122699985764737895162788854942201173538004689536569610046157311527715126074775927977409773971656249943602454790380966869525211733301201659688694473703188427037879868522859419364680904585572399937639393418586498509580133474303442722716959873727260844993296681950092753897902540593927952622713860163782763263944291810729056735965535138964485886748344167499818148134252327820007439830749462775149754781930983094046362696040641091039506998835624218220892441813224657845627120344960554424765109502415773475619490661527184126374299883610442465428985757004551740482644952396990065188807827114495184096249
leak3 = 293130152177150437492580785085598394773458388719469800871702200331766258900690595210759869625006484354799804558552583572062231998451041105464048317708732987121458633718573774164071597186461239762511364549980544029915308083867329707804739776241438307060614946195675715671343671137725809499387682363101164970886
var('p q')
eq = [p*q-n,p+q-leak3]
result = solve(eq,p,q)[0]
print(result)

成功求出p和q

接着我们发现题目并没有给c,继续观察代码,发现如下代码

leak1 = c % q
leak2 = c % p

妥妥的中国剩余定理,sage同样可以很简单的求出c,python的话手撸一个CRT也不难,这里就用sage演示

#sage
p = 161562249983202700035527081166558786031731223261198195999535987465827171883730733359944156020947215855022510635343983292897557354440470230745496731228302894376018866016596714241754815953745113727125200716224341010140868299262202025976056483744622119807303134689795661748036502596285135565503272596613700276343
q = 131567902193947737457053703919039608741727165458271604872166212865939087016959861850815713604059268499777293923208600279164674644010570874718551586480430092745439767701977059922316781232716126035386163833756203019774439784605127681828683292496816187253311811505880053923307168541440673933884409766487464694543
leak1 = 8842431959638543756327530752221031675897458993985909403335303147413741167900365489182674478419510549838159493192002672500346433589707076289344572454304647803237654059883974235710442126617587691632375039292283285577033977676131772115877520248352227419433136507412485140428972344000541898060766721412300525883
leak2 = 127414092867622693231378230621806169422569654246682818498761930473755998913688181327473434110121174292309611256339271412324673262030535400937563769685033472683498585742711576446343086462569783541192470920638935990937187809422965809986860709074542257475025562691683977493260026623616012846939417988284096473040
c_list = [leak2,leak1]
p_q_list = [p,q]
c = CRT_list(c_list,p_q_list)
print(c)


接着发现e也没给,但是给了e的取值范围为: e ≤ 500000 e\leq500000 e500000,所以我们可以尝试爆破一下
下面给出完整代码

#sage
import gmpy2
import libnum
n = 21256406304024147327122699985764737895162788854942201173538004689536569610046157311527715126074775927977409773971656249943602454790380966869525211733301201659688694473703188427037879868522859419364680904585572399937639393418586498509580133474303442722716959873727260844993296681950092753897902540593927952622713860163782763263944291810729056735965535138964485886748344167499818148134252327820007439830749462775149754781930983094046362696040641091039506998835624218220892441813224657845627120344960554424765109502415773475619490661527184126374299883610442465428985757004551740482644952396990065188807827114495184096249
leak1 = 8842431959638543756327530752221031675897458993985909403335303147413741167900365489182674478419510549838159493192002672500346433589707076289344572454304647803237654059883974235710442126617587691632375039292283285577033977676131772115877520248352227419433136507412485140428972344000541898060766721412300525883
leak2 = 127414092867622693231378230621806169422569654246682818498761930473755998913688181327473434110121174292309611256339271412324673262030535400937563769685033472683498585742711576446343086462569783541192470920638935990937187809422965809986860709074542257475025562691683977493260026623616012846939417988284096473040
leak3 = 293130152177150437492580785085598394773458388719469800871702200331766258900690595210759869625006484354799804558552583572062231998451041105464048317708732987121458633718573774164071597186461239762511364549980544029915308083867329707804739776241438307060614946195675715671343671137725809499387682363101164970886
p = 161562249983202700035527081166558786031731223261198195999535987465827171883730733359944156020947215855022510635343983292897557354440470230745496731228302894376018866016596714241754815953745113727125200716224341010140868299262202025976056483744622119807303134689795661748036502596285135565503272596613700276343
q = 131567902193947737457053703919039608741727165458271604872166212865939087016959861850815713604059268499777293923208600279164674644010570874718551586480430092745439767701977059922316781232716126035386163833756203019774439784605127681828683292496816187253311811505880053923307168541440673933884409766487464694543
phi = n - leak3 + 1
c_list = [leak2,leak1]
p_q_list = [p,q]
c = CRT_list(c_list,p_q_list)
print(c)
for e in range(1,5000001):
    try:
        d = gmpy2.invert(e,phi)
        m = pow(c,d,n)
        flag = libnum.n2s(int(m))
        if b'flag' in flag:
            print(flag)
            break
        else:
            continue
    except:
        continue
#b'flag{c59d5fc3-610c-41ca-baef-b26f9a88648d}'

简单的数学

from Crypto.Util.number import *
import libnum
from flag import flag
e = 65537
p = getPrime(1024)
q = getPrime(1024)
n = p*q
k = getRandomNBitInteger(20)
c=pow(libnum.s2n(flag)*p+k*n,e,n)
print(n)
print(k)
print(c)
'''
25014963863951112347974440214066273048882503259160338255496299775995961351901571648895465031685356024238885233929337483853960374743565692563404769039019561050421788096283392820458449077490390195564801845037357811298274797645813808259301937466827199149702646030007667049110326436048932024335483846993690455310182909643176845321021209137548742937430940258997221937352498631551209822079559591857076641561863821325180714184637516327495056825200929458796589533188382551310078527193764723189551017851538326522660734366263229681834096022505151628784267513086843047784002223603418978827233728149657480292961095596638702578233
930971
21332979626247382647148222928588089621511790656630926013612529289276199934646065751526142377438330548167579869346422391777913473113228287023801928140946948279096562923728186040013041739656216576467903409087827269164764659636977412246373447194249307513950780025367450729199178539765363446611686879821064068711525543800807969264271445173422813211738947698740537888866771159352960700295474589207758542367193701819811125602611901272496121027126921035697692984486226677539547135753720071134145590716156803665486826826046693205511230289946748601632769198172373201803516681379607412290191420859001274915183415061321376410345
'''

这是一道看似很难实则很简单的问题,我们展开密文c即可得到: c = ( m ⋅ p + k ⋅ n ) e c=(m \cdot p+k \cdot n)^e c=(mp+kn)e m o d mod mod n n n
我们使用多项式定理展开,得到:
第一项为 ( m ⋅ p ) e (m \cdot p)^e (mp)e,最后一项为 ( k ⋅ n ) e (k \cdot n)^e (kn)e
而它们每一项在 m o d mod mod n n n之后结果均为0
等价于c = ( m ⋅ p ) e (m \cdot p)^e (mp)e m o d mod mod ( p ⋅ q ) (p \cdot q) (pq)
根据模运算规律可得: c p = m e ⋅ p ( e − 1 ) \frac{c}{p} = m^e \cdot p^(e - 1) pc=mep(e1) m o d mod mod q q q
所以c和n的最大公约数就是p,求出p后解密RSA即可

from Crypto.Util.number import *
import gmpy2
n = 25014963863951112347974440214066273048882503259160338255496299775995961351901571648895465031685356024238885233929337483853960374743565692563404769039019561050421788096283392820458449077490390195564801845037357811298274797645813808259301937466827199149702646030007667049110326436048932024335483846993690455310182909643176845321021209137548742937430940258997221937352498631551209822079559591857076641561863821325180714184637516327495056825200929458796589533188382551310078527193764723189551017851538326522660734366263229681834096022505151628784267513086843047784002223603418978827233728149657480292961095596638702578233
k = 930971
e = 65537
c = 21332979626247382647148222928588089621511790656630926013612529289276199934646065751526142377438330548167579869346422391777913473113228287023801928140946948279096562923728186040013041739656216576467903409087827269164764659636977412246373447194249307513950780025367450729199178539765363446611686879821064068711525543800807969264271445173422813211738947698740537888866771159352960700295474589207758542367193701819811125602611901272496121027126921035697692984486226677539547135753720071134145590716156803665486826826046693205511230289946748601632769198172373201803516681379607412290191420859001274915183415061321376410345
p = gmpy2.gcd(n,c)
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n) // p
print(long_to_bytes(m))
#b'flag{The_s3cret_0f_shumu_1s_th1s!}'

每日emo

【我爱山间的清风与广场上的风筝,午夜的马路和清晨的粥铺,已经走远再也不会回头的你。】
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: crypto包是一个提供了加密和解密功能的软件包。它是官方提供的,意味着它是由相关领域的专业人员开发和维护的,并且已经通过了官方的测试和验证。 官方下载指的是从官方网站或者其他官方渠道下载软件包。通过官方下载可以确保软件包的安全性和可靠性。官方下载通常提供了最新版本的软件包,并且会及时更新和修复可能存在的漏洞和问题。 对于crypto包来说,它的官方下载可能提供了多种适用于不同操作系统和编程语言的版本。通过官方下载,我们可以获取到最新的版本,并且能够获取到相关的文档、示例代码和其他支持资源,这有助于我们更好地理解和使用crypto包。 在进行官方下载时,我们应该注意以下几点。首先,确保下载的软件包是来自官方网站或者官方认可的渠道,以避免遭受到恶意软件的攻击。其次,检查下载的软件包的完整性和一致性,以确保没有被篡改或者损坏。最后,及时更新下载的软件包,以获取最新的功能和补丁。 总之,使用官方下载的crypto包可以帮助我们更安全、方便地进行加密和解密操作,并且提供了官方的支持和更新。因此,在使用crypto包时,我们可以选择官方下载,以获取最好的使用体验和保障。 ### 回答2: crypto包是一个用于加密和解密数据的官方下载包。它提供了许多常见的加密算法,如AES、RSA和SHA。该包的目标是提供安全可靠的加密功能,以确保数据的安全性和保密性。 在官方下载页面上,你可以找到适用于不同操作系统和编程语言的版本。通常,您可以选择使用命令行工具或编程语言特定的库来使用crypto包。选择合适的版本后,您可以从website或其他官方渠道下载安装包或源代码。 一旦您将crypto包下载到您的计算机上,您可以按照官方文档中提供的说明进行安装和配置。一般来说,这包括将安装包解压缩到适当的目录,并根据需要设置环境变量。 安装完成后,您就可以在您的代码中使用crypto包来加密和解密数据了。官方文档通常提供了一些示例代码和使用说明,以帮助您快速上手。 需要注意的是,使用crypto包进行加密和解密操作需要遵循一些基本的安全准则。您应该确保使用强密码和安全的密钥管理,并遵循最佳实践来保护您的加密密钥。 总而言之,crypto包是一个功能强大且广泛使用的官方下载包,用于加密和解密数据。通过正确的安装和使用,您可以在您的应用程序中增加数据的安全性和保密性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值