UUCTF CRYPTO 官方WriteUP

本文解析了几道密码学挑战题目,包括使用在线工具解密Rabbit编码、栅栏密码,RSA模数分解,以及利用数学原理解决复杂的RSA问题等。

前言

第一次受邀给比赛出密码学的题目,本人也不是很会密码学,出的题质量都不是很好,给各位师傅道个歉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=p3p^3p3,那么我们就可以求出

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值