[actf-新生赛2020]crypto-classic0、[WUSTCTF2020]B@se1

[actf-新生赛2020]crypto-classic0

题目信息

拿到手有两个压缩包 有一个压缩包是加密的 但是经过提示可以想到这是可以通过暴力破解得到压缩包内容的(虽然开始我没想到) 用ARPR直接破解 开始19000000截止现在的时间就可以

爆破出的压缩包内容是

#include<stdio.h>

char flag[25] = ***

int main()
{
	int i;
	for(i=0;i<25;i++)
	{
		flag[i] -= 3;
		flag[i] ^= 0x7;
		printf("%c",flag[i]);
	}
	return 0; 
}

解释一下这段代码的意思:把明文的每个字符取出来过后 让其ascii码值减去3 然后再和0x7取异或这一点很关键 对于一些不太熟悉python的人 比如我 最开始以为是把每个字符取七次方 然后呆呆地去写脚本 发现根本解不出来)最后得到密文

那么对应的解密思路也很清晰了 倒着来就可以了 把每个字符与0x7取异或再加上3就可以复原了

解密脚本(python)

cipher = "Ygvdmq[lYate[elghqvakl}"
flag=""
for i in cipher:
    i = ord(i)
    i ^=0x7
    i+=3
    flag+=chr(i)
print(flag)

 这道题其实能够想得到用暴力破解的话 就已经成功60%了

[WUSTCTF2020]B@se1

题目信息

根据经验可以知道上面一行是base64加密的 但是直接去解密根本解不出来 这是经过base64扩展加密得到的 而且根据提示可以知道“少了点东西” 仔细看第二行发现是少了四个字符 而且上面一行应该是由下面一行经过base64加密得到的

那么可以遍历得到那四个未曾出现的字符

import string
c = 'JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/'
for i in string.ascii_letters + string.digits:  # string.ascii_letters所有字母  string.digits所有数字
    if(i not in c):
        print(i,end='')
# ju34

 可以确定是 j u 3 4 四个字符

那么具体的思路就是考虑这4!种排列组合 那就有4!种字符串 我们同样可以采用暴力破解 遍历每一种可能

解密脚本

import binascii
import itertools
cipher = 'MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD' # 全排列组合
s = ['j','u','3','4']
for i in itertools.permutations(s,4): # 4就是把s列表里的字母4个为一组排列
    k = "JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs"+ "".join(i) + "kxyz012789+/"  # "".join(i)排列的结果(join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串)
    a = ""
    for j in cipher:
        a += bin(k.index(j))[2:].zfill(6)
    print(binascii.a2b_hex(hex(eval("0b"+a))[2:-1]))  # a2b_hex和binascii.unhexlify可以为16进制的 bytes 类型,也可以为十六进制 str 类型
                                                      # 举例:这里转为16进制后会出现0x471L,所以只有去掉0x和L就有了[2:-1]

对这个脚本进行解释:首先permutations()函数就是一个求排列组合的函数,当传入这四个字符的数组的时候会生成4!种排列组合,而"".join(i)是将每一种可能取出来,然后通过字符串拼接得到了一种可能得字符串。其次,通过遍历全排列组合中的每一个字符,k.index(j)找到字符j在字符串k中的索引。 bin(k.index(j))[2:] 将索引转为二进制字符串,切片去掉开头的0b。zfill(6) 将二进制字符串填充到6位。所以这一个循环的作用就是把每一个在cipher(全排列组合,也就是本来要解密的base64扩展编码)中的字符转换成为六位二进制,最后把这个二进制序列a转换成bytes输出

这道题做下来感觉好难 不看WP对我而言根本做不出来 能走的最远就是把每种可能得字符串输出 但是我并不知道为什么要用cipher的每个字符在k中的索引生成六位二进制,有知道的师傅可以说说嘛

[网鼎杯 2020 青龙组]you_raise_me_up

 题目信息

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import random

n = 2 ** 512
m = random.randint(2, n-1) | 1
c = pow(m, bytes_to_long(flag), n)
print 'm = ' + str(m)
print 'c = ' + str(c)

# m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
# c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499

首先说说在做这道题之前走过的一些弯路 求解e即可 因为e和d天生互素 并且有了d可以通过变形m^e%n=c得到e 但是这样暴力破解时间复杂度太大了 无法求解

这道题是关于离散对数的一道题

关于离散对数

离散对数(Discrete logarithm)是一类重要的数论问题。对于一个素数p,整数g和y,满足关系:g^x ≡ y (mod p) 这里的x称为y关于g在模p意义下的离散对数,记为:x = log_g(y) (mod p)离散对数问题就是给定g、y和p,求x的的值。这是一个在多种公钥密码系统(如DH、ElGamal等)中非常关键的难题。

根据m^e%n=c可知 ,现在已知m,c,n而e未知满足求解离散对数的条件

解密脚本


import  sympy
m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
n = 2 ** 512

e = sympy.discrete_log(n,c,m)
print(hex(e))

求解出来是十六进制 找个在线网站16进制转换,16进制转换文本字符串,在线16进制转换 | 在线工具转字符串就可以了

这道题长知识了,其实如果知道这是离散对数的话就很好做了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值