CTF 中的古典密码学

古典密码学在CTF比赛中主要以代替(substitution)密码和置换(permutatuion)密码两种形式出现,出题人有时候也喜欢自己胡诌一些编码方式令人摸不清头脑,下面就是一种非常有代表性的富有脑洞的替换密码。
image.png

这是月相密码,由阿根廷艺术家Leandro Katz利用从新月到满月的最具代表性的26个月相所组成。

编码

0x01 Base64编码

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。26=64,所以每6bit为一个单元,对应某个可打印字符。3字节有24bit,对应4个Base64单元,即3字节任意二进制数据可由4个可打印字符来表示。在Base64中,可打印字符包括字母A~Z、a~z和数字0~9,共62个字符,以及+、/字符。Base64常用于只能处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME电子邮件、XML复杂数据等。
image.png

需要注意的是,在Base编码的家族中,Base16就是Hex编码,因此需要16进制转换的时候可以直接调用Pythonbase64包进行加解密
Base100经常以表情包的形式出现,好像还挺常见的样子

0x02 Morse Code

一款经典的替换密码,常见于各种谍报剧中
image.png

0x03 Escape编码

Escape/Unescape加密解码/编码解码,又叫%u编码,采用UTF-16BE模式, Escape编码/加密,就是字符对应UTF-16的16进制表示方式前面加%u。Unescape解码/解密,就是去掉”%u”后,将16进制字符还原后,由utf-16转码到自己目标字符。如:字符“中”,UTF-16BE是:“6d93”,因此Escape是“%u6d93”。

代码混淆加密

BrainFuck

image.png

1
,----------[----------------------.,----------]

脑操嘛,上面这一大坨代码的作用就是把一个字符的ASCII值减去32,实现小写转大写的功能。简单易懂是不可能的。

Ook

image.png
Brainfuck的变种,用 . ? ! 三种符号对其进行了改编。当然,你嫌Ook太多碍事把Ook删掉也是一样的。只保留 . ? ! ,但是这仍然是 Ook 编码

Pikalang

image.png
一款基于皮卡丘和Brainfuck的编码,希望你对皮卡丘的喜爱能胜过对Brainfuck的厌恶
image.png

JSfuck

image.png
基于 JavaScript 特性和 Brainfuck 思想的优秀编码法……建议是直接丢浏览器控制台里运行。

替换加密

0x01 埃特巴什码

以字母倒序排列作为特殊密钥的替换加密,也就是下面的对应关系:

1
2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBA

0x02 凯撒密码

凯撒密码是一种最简单且广为人知的加密技术。它是一种移位加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3时,所有字母A将被替换成D、B变成E,以此类推。这种加密方法是以罗马共和国时期凯撒的名字命名的,当年凯撒曾用此方法与其将军们进行联系。

Rot5

针对数字的凯撒密码,偏移值为5,加密两次后为原数字,Rot 是rotate的缩写

Rot13

针对字母的凯撒密码,偏移值为13,加密两次后为原文

Rot 18

简单的数学运算, $5 + 13 = 18$ ,把 Rot5 和 Rot13 组合起来就是Rot18

Rot 47

针对特殊符号的一种加密,弥补了Rot18 无法对 @ # $ 等特殊符号加密的缺陷,Rot47针对 ASCII 的范围是 33-126 这一段可见字符,同样存在循环。

0x03 猪圈密码

image.png
image.png

圣堂武士密码

猪圈密码的变种
image.png

0x04 银河密码

image.png

0x05 维吉尼亚密码

image.png
维吉尼亚密码是一种简单的多表代换密码(由26个类似的Caesar密码的代换表组成),
即由一些偏移量不同的恺撒密码组成,这些代换在一起组成了密钥。

0x06 培根密码

培根密码是由法兰西斯·培根发明的一种隐写术,加密时,明文中的每个字母都会转换成一组5个英文字母,如下表
image.png

0x07 仿射密码

仿射密码是一种替换密码。它是一个字母对一个字母的。加密函数是 $e(x) = ax+b(mod\ m)$ 其中,$a$ 与 $m$ 互质
解密公式:$d(x) = a^{-1}(x-b)\ mod \ m$ ,需要一些乘法逆元的知识。

0x08 云影密码

01248密码又称为云影密码,使用 0,1,2,4,8 四个数字,其中 0 用来表示间隔,其他数字以加法可以表示出 如:28=10,124=7,18=9,再用 1->26 表示 A->Z。

换位加密

栅栏密码

栅栏密码(Rail-fence Cipher)就是把要加密的明文分成N个一组,然后把每组的第1个字符组合,每组第2个字符组合…每组的第N(最后一个分组可能不足N个)个字符组合,最后把他们全部连接起来就是密文
假设明文为“wearefamily”,密钥为“4”,先用密钥“4”将明文每4个字符分为一组“wear||efam||ily”,然后依次取出每组第1、2、3个字母,组为“wei||efl||aay||rm”,再连接起来就可以得到密文“weieflaayrm”。

W型栅栏

于栅栏密码中,明文由上至下顺序写上,当到达最低部时,再回头向上,一直重复直至整篇明文写完为止。然后,再往右顺序抄写一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
原文:helloworldgoodmorningxxxx   5层栅栏

h l r x
e r d o n x
l o g m i x
l w o d n x
o o g

密文:hlrnerdonilogmiqlwodnxoog

原文:helloworldgoodmorningxxxx 4层栅栏


h o o i x
e w r o d n n x
l o l g m r g x
l d o x

密文:hooixewrodnnxlolgmrgxldox

参考

CTF中那些脑洞大开的编码和加密 - jack_Meng - 博客园 (cnblogs.com)
Nu1L Team 战队编写的 《从0到1:CTFer成长之路》
Esolang, the esoteric programming languages wiki (esolangs.org)
简介 - CTF Wiki (ctf-wiki.org)