[HDCTF2019]together、[NPUCTF2020]Classical Cipher、

[HDCTF2019]together

题目信息

 

拿到手就是两个公钥包 两个密文包 观察公钥包中的内容发现是可以公钥分解的

分解后可以得到两个指数e1=2333,e2=23333,并且模数相同,很明显这就是共模攻击,直接套用之前写的脚本即可

注意:此处c1和c2看起来确实是base64加密的,事实上确实是,但是使用base64解码无用,因为base64只是一种编码方式,使用base64解密能解出个什么玩意?最多给你个乱码字符串,我们的目的是要得到整数,所以需要先转换成为unicode后再转换成为长整型数字。

对公模攻击证明过程以及解释更详细的解释 之前有写过 参考这里

解密脚本

import base64
import binascii

import gmpy2
from Crypto.Util.number import bytes_to_long, long_to_bytes

#把两个base编码的字符串转换成数字
c1_encode = "R3Noy6r3WLItytAmb4FmHEygoilucEEZbO9ZYXx5JN03HNpBLDx7fXd2fl+UL5+11RCs/y0qlTGURWWDtG66eNLzGwNpAKiVj6I7RtUJl2Pcm3NvFeAFwI9UsVREyh7zIV6sI9ZP8l/2GVDorLAz5ULW+f0OINGhJmZm8FL/aDnlfTElhQ87LPicWpXYoMtyr6WrxjK6Ontn8BqCt0EjQ7TeXZhxIH9VTPWjDmFdmOqaqdVIT+LZemTgLNESwM5nn4g5S3aFDFwj1YiDYl0/+8etvKfOrfoKOwR0CxsRHagwdUUTES8EcHLmMGCxCkDZn3SzmmA6Nb3lgLeSgG8P1A=="
c2_encode = "O+rRCXI3aTB6P1rYIOPUdalUp6ujpwEq4I20CoWA+HIL8xxGtqY6N5gpr0guZv9ZgOEAMFnBxOqMdVNnB9GgnhmXtt1ZWydPqIcHvlfwpd/Lyd0XSjXnjaz3P3vOQvR71cD/uXyBA0XPzmnTIMgEhuGJVFm8min0L/2qI7wg/Z7w1+4mOmi655JIXeCiG23ukDv6l9bZuqfGvWCa1KKXWDP31nLbp0ZN2obUs6jEAa1qVTaX6M4My+sks+0VvHATrAUuCrmMwVEivqIJ/nS6ymGVERN6Ohnzyr168knEBKOVj0FAOx3YLfppMM+XbOGHeqdKJRLpMvqFXDMGQInT3w=="

c1 = bytes_to_long(base64.b64decode(c1_encode))
c2 = bytes_to_long(base64.b64decode(c2_encode))
# print(c1)
# print(c2)
# 步骤:1.先寻找s1,s2
# 2.套公式求明文
import gmpy2
n = 14853081277902411240991719582265437298941606850989432655928075747449227799832389574251190347654658701773951599098366248661597113015221566041305501996451638624389417055956926238595947885740084994809382932733556986107653499144588614105694518150594105711438983069306254763078820574239989253573144558449346681620784979079971559976102366527270867527423001083169127402157598183442923364480383742653117285643026319914244072975557200353546060352744263637867557162046429886176035616570590229646013789737629785488326501654202429466891022723268768841320111152381619260637023031430545168618446134188815113100443559425057634959299
e1 = 2333
e2 = 23333

r, s1, s2 = gmpy2.gcdext(e1, e2)  # 这里使用的是扩展欧几里得,r是s1和s2的最大公因子,s1和s2是我们要求的数
m = (pow(c1, s1, n) * pow(c2, s2, n)) % n
print("找到的明文是:")
print(hex(m))
print(binascii.unhexlify(hex(m)[2:]))

这道题也就是难在c1和c2转换成为长整型数字的过程

[NPUCTF2020]Classical Cipher

 题目信息

观察密文 用凯撒爆破即可 得到两个貌似可以的answer 都尝试一下即可

爆破网站:quipqiup - cryptoquip and cryptogram solver

打开图片压缩包后 得到如下图片

很明显是扩展猪圈密码 对应的参考网站CTF中的一些图形密码 - 自由资讯

 

 

一一比对即可得到flag:CLASSICALCODE

提交的时候记得改为小写

[BJDCTF2020]Polybius

题目信息

把hint用Base64解密后 得到hint

 因为密文是a e i o u的组合 那么原文的可能就有5!种可能。但是我们需要考虑的是在polybius中

 

  1 2 3 4 5
1 A B C D E 
2 F G H I/J K
3 L M N O P
4 Q R S T U
5 V W X Y Z

 I/J是处于同一个单元中的,所以原本的单元中原文的可能还要乘2,即5!*2种可能。那么根据原文长度是14的条件下,暴力输出每种可能的序列,再观察即可得到flag

解密脚本

import itertools
s="aeoiu"
sumresult=[]
numsumresult=[]
ciper="ouauuuoooeeaaiaeauieuooeeiea"
for i in itertools.permutations(s,5):#找出所有全排列
    sumresult.append("".join(i))
for i in sumresult:
    temp=""
    for j in ciper:
        temp+=str(i.index(j)+1)
    numsumresult.append(temp)
for i in numsumresult:
    ans_=""
    for j in range(0, len(i),2):
        xx=(int(i[j])-1)*5+int(i[j+1])+96
        if xx>ord('i'):
            xx+=1
        ans_+=chr(xx)
    print(ans_)



解释一下代码的意义:

1. 生成所有可能的5×5矩阵排列使用itertools.permutations生成所有长度为5的字符串s的全排列,也就是所有可能的5×5矩阵排列。

2. 将密文转换为坐标对每个可能的矩阵,把密文中的每个字母转成矩阵中的坐标(行数和列数),concat成新的字符串。

3. 坐标转回字母对每个坐标字符串,遍历2位一组,根据行列编号反推矩阵中对应的字母。这里有个+1的操作是因为矩阵下标从0开始,而坐标是从1开始的。最后ord和chr用于字母和ASCII码之间的转换。

4. 打印可能的明文对每个矩阵排列都做上述转换,打印出所有可能的明文。

[BJDCTF2020]编码与调制

题目信息

猜测是曼彻斯特编码

关于曼彻斯特编码

有不同的规则,比较主流的是G.E.Thomas的,0对应01,低-高电平,1对应10,高-低电平

举个例子,有一段二进制数据,1000

1→10

0→01

所以,1000→10010101,这就是经过曼彻斯特编码后的数据

解码也同样,比如有很长一段二进制数据,可以两位两位地看,按照映射的规则,反推出原文。比较方便的解码方法是四位一并,得到一个一个的小的单元,在每个单元中的第一位加上第三位就是原文数据

比如,10010101按照四位一并可以分为 1001 0101

在1001这个单元中第一位和第三位是(从左往右看)1 0

那么1001的原文数据就是10

同理在0101中的第一位和第三位是0 0

那么0101的原文数据是00

解码脚本


from Crypto.Util.number import *

txt = '2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6'

temp = ''
for i in txt:
    pd = bin(int(i,16))[2:].zfill(4)
    temp += pd[0] + pd[2]#10->1   01->0

flag = ''
for i in range(0,len(temp),8):
    flag +=hex(eval('0b'+temp[i:i+8]))[2:]

print(long_to_bytes(eval('0x'+flag)))

也可以用在线网站破解 选择G.E.Thomas标准即可

Online Manchester decoder/encoder ‐ eleif.net

不过需要自己提前转换成为二进制 输出也是二进制 需要转换成十六进制再转字符

转换成二进制:

10010101011001011001011001100101100101011001010110101010011010011001010110010101101001100101100110100101101001011001011010011001101001010101100110100110101001011010010101101001101001100101010110100101100110011010100101101001101010011001010110100101100110011010100101100101101001010110100110100110101010011010010110010101101001011001100110101010100110

输出结果:

1000010010010100100010001111011010001000110100101100110010011010110000101101110011000110110100001100101011100110111010001100101011100100110001101101111011001000110010101111101

输出结果转化成十六进制:

0x424a447b4469664d616e63686573746572636f64657d

十六进制转换成字符:

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值