ctf古典密码从0到
本文首发于“合天智汇”公众号 作者:淡灬看夏丶恋雨
- 古典密码和现代密码的区别:
- 代换密码
- 单表代换密码
- 字符或数学型
- 凯撒密码
- 仿射密码
- 四方密码
- 培根密码
- 图表
- 标准银河字母
- 圣堂武士密码
- 猪圈密码
- 当铺密码
- 跳舞的小人密码
- 多表代换密码
- 希尔密码
- 维吉尼亚密码
- 棋盘密码(Polybius)
- 普莱费尔密码(playfair)
- Nihilist密码
- Keyboard密码
- 移位密码
- 栅栏密码
- 云影密码
- 简单位移密码
- 曲路密码
4.CTF crypto线下工具推荐
古典密码和现代密码的区别:
古典密码是密码学中的其中一个类型,其大部分加密方式都是利用替换式密码或移项式密码,有时则是两者的混合。其于历史中经常使用,但现代已经很少使用,大部分的已经不再使用了。一般而言,经典密码是基于一个拼音字母(像是 A-Z)、动手操作或是简单的设备。它们可能是一种简单的密码法,以致于不可信赖的地步,特别是有新技术被发展出来后。
现代的方法是用电脑或是其它数字科技,基于比特和字节上操作。许多经典密码被受尊重的人使用,像是尤利乌斯·凯撒和拿破仑,他们创造了一些常被人们使用的密码。许多密码起源于军事上,相同立场的人常使用来寄送秘密消息。经典的方法常攻击密码文,有时候甚至不知其密码系统,也可以使用工具,像是频率分析法。有些经典密码是使用先进的机器或是机电密码机器,像是恩尼格玛密码机。 ---维基
其中,古典密码学,作为一种实用性艺术存在,其编码和破译通常依赖于设计者和敌手的创造力与技巧,并没有对密码学原件进行清晰的定义。古典密码学主要包含以下几个方面:
单表替换加密(Monoalphabetic Cipher)
多表替换加密(Polyalphabetic Cipher)
奇奇怪怪的加密方式 --ctf wiki
凯撒密码:
凯撒曾经使用这种密码与其将军们来联系,所以用凯撒来命名这种密码。
根据图片来了解加密原理。凯撒密码一般适用于26个英文字母。根据偏移量来进行加密。如图所示,当偏移量=3。即是A-D,B-E。
把字母转成数学,数学公式如下。
在线加解密网站:
https://www.qqxiuzi.cn/bianma/kaisamima.php
http://www.metools.info/code/c70.html
http://www.atoolbox.net/Tool.php?Id=778
仿射密码:
数学加密公式:
仿射密码中解密需要用到求逆元
直接给出python解密脚本:
import primefac def affine_decode(c,a,b,origin="abcdefghijklmnopqrstuvwxyz"): r="" n=len(origin) ai=primefac.modinv(a,n)%n for i in c: if origin.find(i)!=1: r+=origin[(ai*(origin.index(i)-b))%n] else: r+=i return r print affine_decode("ihhwvcswfrcp",5,8) def affine_guessab(m1,c1,m2,c2,origin="abcdefghijklmnopqrstuvwxyz"): x1=origin.index(m1) x2=origin.index(m2) y1=origin.index(c1) y2=origin.index(c2) n=len(origin) dxi=primefac.modinv(x1-x2,n)%n a=dxi*(y1-y2) % n b=(y1-a*x1)%n return a,b print affine_guessab("a","i","f","h")
仿射密码在线加解密网站:
http://www.atoolbox.net/Tool.php?Id=911
仿射密码真题-one:
Buuctf- Crypto-[GKCTF2020]小学生的密码学
e(x)=11x+6(mod26)
密文:welcylk
(flag为base64形式)
四方密码:
四方密码是一种对称式加密法,由法国人Felix Delastelle(1840年–1902年)发明。
这种方法将字母两个一组,然后采用多字母替换密码。
四方密码用4个5×5的矩阵来加密。每个矩阵都有25个字母(通常会取消Q或将I,J视作同一样,或改进为6×6的矩阵,加入10个数字)。
选两个密钥,example和keyword。去掉重复的字母。就是example变成exampl。余下的字母顺序存入矩阵即可
加密矩阵放右上和左下。
加密步骤。把字符串按两个字母一组分开
Helloworld
He ll ow or ld
找第一组第一个字母在左上角矩阵的位置:
找第一组第二个字母在右下角矩阵的位置:
先找和一个字母同横的,和第二个字母同直的
第一个字母同直,第二个字母同横的
得到he加密后为FY
如此可得接下来,最后就是
he lp me ob iw an ke no bi
FY GM KY HO BX MF KK KI MD
四方密码真题-one:
Buuctf-crypo-四面八方
四方密码:
wiki上了解四方密码如何加解密的一个过程
https://zh.wikipedia.org/wiki/%E5%9B%9B%E6%96%B9%E5%AF%86%E7%A2%BC
密钥存阵
通常在题目中会给定2个密钥,我们要去掉Q或者把I和J当成一个。按照26个英文字母。秘钥中出现的不填。补充成5*5的矩阵
这题直接填充即可
securityabdfghjklmnopvwxz
securityadbfghjklmnopvwxz
abcdefghijklmnopqrstuvwxyz
informatn
informatbcdeghjklpsuvwxyz
abcdefghijklmnopqrstuvwxyz
在线解密工具:
http://ctf.ssleye.com/four.html
根据题目说的解出来的语句是个通顺的句子,那肯定排序就有点问题
接下来可以拿出词频分析。
这边分割可以多试试。可以看出来个success,其他位置试
https://quipqiup.com/
四方密码在线加解密网站:
http://ctf.ssleye.com/four.html
培根密码:
培根密码直接根据表中的字母进行转换。
密文一般只含有a和b字母
培根密码在线解密:
https://tool.bugku.com/peigen/
培根密码真题-one:
攻防世界crypto新手-不仅仅是morse
把/转换成空格。直接拿出morse解密
在看后面一段像培根密码,根据题目提示是食物加密。
标准银河字母:
标准银河字母(Standard Galactic Alphabet)出自游戏《指挥官基恩》系列。是系列中使用的书写系统。这是一个简单的替代暗号,用不同的符号取代拉丁字母。SGA可以在不同的语言中使用,比如在游戏《Minecraft》,《指挥官基恩》中。
如果遇到这类题。直接根据题目来进行图翻->字母
圣堂武士密码:
圣堂武士密码(Templar Cipher)是共济会的“猪圈密码”的一个变种,一直被共济会圣殿骑使用。
直接根据图片上的直接翻译出字母即可
猪圈密码:
猪圈密码(亦称朱高密码、共济会暗号、共济会密码或共济会员密码),是一种以格子为基础的简单替代式密码。即使使用符号,也不会影响密码分析,亦可用在其它替代式的方法。
直接图片替换字母即可
猪圈密码在线解密网站:
http://www.metools.info/code/c90.html
猪圈密码真题:
Buuctf-crypto-萌萌哒的八戒
直接解密
猪圈密码-圣堂武士密码-标准银河字母-栅栏密码真题:
Buuctf-Crypto- [MRCTF2020]古典密码知多少
图上的蓝色就是猪圈密码,橙色的是圣堂武士密码,黑色的是银河字母。
当铺密码:
当铺密码就是一种将中文和数字进行转化的密码,算法相当简单:当前汉字有多少笔画出头,就是转化成数字几。例如:
口 0 田 0 由 1 中 2 人 3 工 4
大 5 王 6 夫 7 井 8 羊 9
具体映射可查看:
https://www.cnblogs.com/cc11001100/p/9357263.html
当铺密码真题:
Buuctf-crypto-GKCTF2020汉字的秘密
直接解码发现不对。
翻看ascii码。改进一下脚本:
自己猜一下flag开头为flag。可以看到ascii嘛每一位都是递增的。
差为1,2,3,4
跳舞的小人密码:
跳舞的人,讲的是一个黑帮发明的一种密码,其密码就是用一个一个的跳舞的小人组成的,一个小人是一个字母。有人用这种密码进行通信,来威胁某人,福尔摩斯后来破解了这个密码,抓住了坏人。
这题直接根据表来进行转换即可。加解密同
这题感觉是做过的。但没翻到例题。就不放了。
希尔密码(hill):
希尔密码(Hill Cipher)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果MOD26。
直接给出网上的脚本可以参考:
import numpy as np m = 'YOURPINNOISFOURONETWOSIX' #明文 a = np.matrix([[11,2,19],[5,23,25],[20,7,17]]) #密钥LCTFXZUHR num_m = [] temp = [] count = 1 for i in m: #将明文分为三个一组 temp.append(ord(i)-ord('A')) if count % 3 == 0: num_m.append(temp) temp = [] count += 1 mat_m = [np.matrix(i).T for i in num_m] #将明文分组转换为向量形式 mat_c = [a * i % 26 for i in mat_m] #得到密文分组的向量形式 num_c = [] temp = [] for i in mat_c: #将密文向量转换为列表形式,且合并到一个列表 temp = i.tolist() for j in range(3): num_c.append(temp[j][0]) c = [chr(i+ord('A')) for i in num_c] print(''.join(c)) #连接成字符串,输出密文
希尔密码在线加解密:
http://www.atoolbox.net/Tool.php?Id=914
维吉尼亚密码:
维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。
维吉尼亚加解密表格:
当明文为
ATTACKATDAWN
选择某一关键词并重复而得到密钥,如关键词为LEMON时,密钥为:
LEMONLEMONLE
对于明文的第一个字母A,对应密钥的第一个字母L,于是使用表格中L行字母表进行加密,得到密文第一个字母L。类似地,明文第二个字母为T,在表格中使用对应的E行进行加密,得到密文第二个字母X。以此类推,可以得到:
明文:ATTACKATDAWN
密钥:LEMONLEMONLE
密文:LXFOPVEFRNHR
维吉尼亚密码在线加解密:
https://www.qqxiuzi.cn/bianma/weijiniyamima.php
维吉尼亚密码真题-one:
BUUCTF-Crypto-[BJDCTF 2nd]燕言燕语-y1ng
小燕子,穿花衣,年年春天来这里,我问燕子你为啥来,燕子说:
79616E7A69205A4A517B78696C7A765F6971737375686F635F73757A6A677D20
16进制转字符串
维吉尼亚在线直接解
棋盘密码(Polybius):
波利比奥斯棋盘(Polybius Checkerboard)是棋盘密码的一种,是利用波利比奥斯方阵(Polybius Square)进行加密的密码方式,产生于公元前两世纪的希腊,相传是世界上最早的一种密码。简单的来说就是把字母排列好,用坐标的形式表现出来。字母是密文,明文便是字母的坐标。
借鉴知乎上的图
先看纵向,在看横向。得到密文
明文HELLO 密文:23 15 31 31 34
普莱费尔密码(playfair):
选取一个英文字作密钥。除去重复出现的字母。将密钥的字母逐个逐个加入5×5的矩阵内,剩下的空间将未加入的英文字母依a-z的顺序加入。(将Q去除,或将I和J视作同一字。)
将要加密的讯息分成两个一组。若组内的字母相同,将X(或Q)插入两字母之间,重新分组(例如 HELLO 将分成 HE LX LO)。若剩下一个字,也加入X字。
在每组中,找出两个字母在矩阵中的地方。
若两个字母不在同一直行或同一横列,在矩阵中找出另外两个字母,使这四个字母成为一个长方形的四个角。
若两个字母在同一横列,取这两个字母右方的字母(若字母在最右方则取最左方的字母)。
若两个字母在同一直行,取这两个字母下方的字母(若字母在最下方则取最上方的字母)。
取playfair example为密钥。即可得到表
P L A Y F
I R E X M
B C D G H
K N O Q S
T U V W Z
需要加密的为Hide the gold
HI DE TH EG OL
加密后为
BM OD ZB XD
在线普莱费尔加解密:
http://www.atoolbox.net/Tool.php?Id=912
http://rumkin.com/tools/cipher/playfair.php
普莱费尔真题-one:
Buuctf-crypto-cipher
还能提示什么呢?公平的玩吧(密钥自己找) Dncnoqqfliqrpgeklwmppu 注意:得到的 flag 请包上 flag{} 提交, flag{小写字母}
http://rumkin.com/tools/cipher/playfair.php
Nihilist密码:
Nihilist跟polybius密码差不多
相同的先看纵向,在看横向。
例如a=[2,3]=23
Keyboard密码:
Keyboard密码在ctf中应该是分多种类型的。这里提两种。即9键表和26键包含
9键表就是通过九键上多次字母来进行字母提取
26键包含通过明文多个字符对应一个密文
9键表真题:
直接放两道题来理解
Buuctf- Crypto-[NCTF2019]Keyboard
分析第一个字符串,ooo,o在键盘上对应的是9,有3个o,表示第9个格子的第三个字母,就是y。那yyy就是指字母o
cipher="ooo yyy ii w uuu ee uuuu yyy uuuu y w uuu i i rr w i i rr rrr uuuu rrr uuuu t ii uuuu i w u rrr ee www ee yyy eee www w tt ee" base=" qwertyuiop" a=[" "," ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"] #print(base.index("q")) for part in cipher.split(" "): s=base.index(part[0]) count=len(part) #print(a[9][2],end="") print(a[s][count-1],end="")
第一步:
构造3个需要的值,变量和列表
cipher就是题目附件的字符串
base就是键盘上一行对应的数字,第一个为空。因为索引的时候,第一个为0。使得q正好为1
a列表第一个的空格字符串同理。也是0。如下走下来空格对应九格键盘上的1,abc就对应九格键盘上的数字2,def对应3。
第二步:
index就是索引的值,就是取键盘上的数字
a[][]。列表的两次,就直接取对应的字母了。end是为了不换行。
count的减1,还是因为第一个是0
Buuctf- Crypo-[MRCTF2020]keyboard
得到的flag用
MRCTF{xxxxxx}形式上叫
都为小写字母
6
666
22
444
555
33
7
44
666
66
3
str="6 666 22 444 555 33 7 44 666 66 3" a=[" "," ","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"] for i in str.split(" "): s=int(i[0]) count=len(i) print(a[s][count-1],end="")
这边解出来最后一个字母是d。但提交不上。搜一下这个单词就知道最后一个应该打错了。是e
26键包含真题:
实验吧-密码学-keyword
根据题目hint:应该。是键盘包围,或者画图
BHUK,LP TGBNHGYT BHUK,LP UYGBN TGBNHGYT BHUK,LP BHUK,LP TGBNHGYT BHUK,LP TGBNHGYT UYGBN
空格划组 逗号也算一个里面
直接画出来
NBNCBNNBNBC
栅栏密码:
栅栏密码是典型的置换密码。把明文分成n个1组。在进行连接。根据如何连接,又分为普通栅栏密码(|||栅栏密码)和W型栅栏密码。
普通栅栏密码(|||栅栏密码)
值和n:
fslda1g2{3a}
n=2
按2个分组
fs ld a1 g2 {3 a}
取第一个
flag{a
在取全部
flag{asd123}
普通栅栏密码(|||栅栏密码)真题-one:
Buuctf-Crypto-篱笆墙的影子
直接两栏获得flag
w型栅栏密码
写成W型的栅栏密码。但读取还是按行从左往右读取。
值和n:
flag{asd123}
n=2
照样是2个分组
f.a.{.s.1.3
.l.g.a.d.2.}
直接从左往右读取
fa{s13lgad2}
W型栅栏密码真题-one:
攻防世界Crypto新手-Railfence
根据题目名和题目描述可知是栅栏密码。
但不是普通的|||型栅栏密码
是变种的W型栅栏密码
在线解密:
http://www.atoolbox.net/Tool.php?Id=777
手解:
把值按照W型进行横排排列,把明文的第一个填充到密文的第一行第1个位置,把明文的第二个填充到密文的第一行第9个位置。在把明文的第三个填充到密文的第17个位置。在把明文的第四个填充到密文的第25个位置。在把明文的第五个填充到密文的第33个位置。
当len=35,key=5时(这个就自己画一画吧)然后你就会发现:首行和尾行的间隔依旧不变,假设行数为i,当当前数为第2行的奇数的时候,下一个数字为2+6=8也就是(key-i)*2,若当前数为第二行偶数的时候,下一个数字为8+2=10也就是(i-1)*2。
普通栅栏密码加解密:
https://www.qqxiuzi.cn/bianma/zhalanmima.php
W型栅栏密码在线加解密:
http://www.atoolbox.net/Tool.php?Id=777
云影密码:
有1,2,4,8这四个数字,可以通过加法来用这四个数字表示0-9中的任何一个数字,列如0=28, 也就是0=2+8,同理7=124, 9=18。这样之后再用1-26来表示26个英文字母,就有了密文与明文之间的对应关系。引入0来作为间隔,以免出现混乱。所以云影密码又叫“01248密码”。
也给出一个python脚本地址:
https://www.jianshu.com/p/b5aa5cf60f83
#!/usr/bin/python # -*- coding=utf8 -*- """ # @Author : pig # @CreatedTime:2019-11-2423:54:02 # @Description : """ def de_code(c): dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)] flag = [] c2 = [i for i in c.split("0")] for i in c2: c3 = 0 for j in i: c3 += int(j) flag.append(dic[c3 - 1]) return flag def encode(plaintext): dic = [chr(i) for i in range(ord("A"), ord("Z") + 1)] m = [i for i in plaintext] tmp = [];flag = [] for i in range(len(m)): for j in range(len(dic)): if m[i] == dic[j]: tmp.append(j + 1) for i in tmp: res = "" if i >= 8: res += int(i/8)*"8" if i%8 >=4: res += int(i%8/4)*"4" if i%4 >=2: res += int(i%4/2)*"2" if i%2 >= 1: res += int(i%2/1)*"1" flag.append(res + "0") print ("".join(flag)[:-1]) c = input("输入要解密的数字串:") print (de_code(c)) m_code = input("请输入要加密的数字串:") encode(m_code)
简单位移密码:
这个密码是我在《ctf特训营》这本书上看到的。自己并没有在题目中做到过
实例借鉴书中
m=flag{easy_easy_crypto}
k=”3124”
len(k)=4,切分m。
flay {eas y_ea sy_c rypt o}
按照3124直接排列
Lafg ea{s _eya y_sc yprt }o
密文:
Lafgea{s_eyay_scyprt}o
解密代码:
def shift_decrypt(c,k): l=len(k) m="" for i in range(0,len(c),l): tmp_m=[""]*l if i+l>=len(c): tmp_c=c[i:] use=[] for kindex in range(len(tmp_c)): use.append(int(k[kindex])-l) use.sort() for kindex in range(len(tmp_c)): tmp_m[kindex]=tmp_c[use.index(int(k[kindex])-l)] else: tmp_c=c[i:i+l] for kindex in range(len(tmp_c)): tmp_m[kindex]=tmp_c[int(k[kindex])-1] m+="".join(tmp_m) return m c="lafgea{s_eyay_scyprt}o" k="3124" print shift_decrypt(c,k)
曲路密码:
按照事先约定的原则把明文填入表中
例如:明文为HelloWorldab
按照一定的顺序进行遍历
密文就是lrbaoleWdloH
CTF crypto线下工具推荐:
CTFCrackTools
https://github.com/Acmesec/CTFCrackTools
CyberChef
https://www.chinabaiker.com/cyberchef.htm
直接可以下载到本地
文中如果有错有什么问题。可以私聊告知:qq1969434293。合天群里也有我。嘻嘻嘻嘻嘻嘻
参考:
https://ctf-wiki.github.io/ctf-wiki/crypto
《ctf特训营》
相关实验:
相关实验:密码学原理
(密码学是研究如何隐密地传递信息的学科。通过本课程实验掌握密码学的相关知识。)