ctf古典密码从0到

本文首发于“合天智汇”公众号 作者:淡灬看夏丶恋雨

  1. 古典密码和现代密码的区别:
  2. 代换密码
  3. 单表代换密码
  4. 字符或数学
  5. 凯撒密码
  6. 仿射密码
  7. 四方密码
  8. 培根密码
  9. 图表
  10. 标准银河字母
  11. 圣堂武士密码
  12. 猪圈密码
  13. 当铺密码
  14. 跳舞的小人密码
  15. 多表代换密码
  16. 希尔密码
  17. 维吉尼亚密码
  18. 棋盘密码(Polybius)
  19. 普莱费尔密码(playfair)
  20. Nihilist密码
  21. Keyboard密码
  22. 移位密码
  23. 栅栏密码
  24. 云影密码
  25. 简单位移密码
  26. 曲路密码

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

https://zh.wikipedia.org/wiki

https://baike.baidu.com

《ctf特训营》

https://buuoj.cn/

 

相关实验:

相关实验:密码学原理

https://sourl.cn/v9atr5

(密码学是研究如何隐密地传递信息的学科。通过本课程实验掌握密码学的相关知识。)

 

posted @ 2020-09-07 18:00  合天网安实验室  阅读(1678)  评论(0编辑  收藏  举报