古典密码学

算是CTF密码学的入门部分了,各大赛事有时候会出一个当签到题,基本也都能用随波逐流工具一把梭,所以一些算法的脚本也就基本用不上了,但是还是记录一下。

凯撒密码

凯撒密码(Caesar)加密时会将明文中的 每个字母 都按照其在字母表中的顺序向后(或向前)移动固定数目(循环移动)作为密文

举个例子,如果偏移量为3的话,那就是将明文的每个字母都往后移动3位,如果超出z了就往前重复,相当于一个模26的域

1
2
明文:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文:DEFGHIJKLMNOPQRSTUVWXYZABC

根据偏移量的不同,还存在若干特定的恺撒密码名称

  • 偏移量为 10: Avocat (A→K)
  • 偏移量为 13: ROT13
  • 偏移量为 -5: Cassis (K→6)
  • 偏移量为 -6: Cassette (K→7)

一般用的比较多的就是ROT13加密了,就是移动13位,没啥好说的

加密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def encrypt_caesar_cipher(plaintext):
def shift(text, n):
result = ""
for char in text:
if char.isalpha():
shift = ord(char) + n
if char.islower():
if shift > ord("z"):
shift -= 26
elif shift < ord("a"):
shift += 26
elif char.isupper():
if shift > ord("Z"):
shift -= 26
elif shift < ord("A"):
shift += 26
result += chr(shift)
else:
result += char
return result

print("尝试所有可能的位移:")
for i in range(1, 26):
print(f"位移 {i}: {shift(plaintext, +i)}")


if __name__ == "__main__":
plaintext = input("请输入凯撒密码的明文:")
encrypt_caesar_cipher(plaintext)

解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def decrypt_caesar_cipher(ciphertext):
def shift(text, n):
result = ""
for char in text:
if char.isalpha():
shift = ord(char) + n
if char.islower():
if shift > ord("z"):
shift -= 26
elif shift < ord("a"):
shift += 26
elif char.isupper():
if shift > ord("Z"):
shift -= 26
elif shift < ord("A"):
shift += 26
result += chr(shift)
else:
result += char
return result

print("尝试所有可能的位移:")
for i in range(1, 26):
print(f"位移 {i}: {shift(ciphertext, -i)}")


if __name__ == "__main__":
ciphertext = input("请输入凯撒密码的密文:")
decrypt_caesar_cipher(ciphertext)

Atbash Cipher

埃特巴什码(Atbash Cipher),它使用字母表中的最后一个字母代表第一个字母,倒数第二个字母代表第二个字母

1
2
明文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文:Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

加密例子:

1
2
明文:the quick brown fox jumps over the lazy dog
密文:gsv jfrxp yildm ulc qfnkh levi gsv ozab wlt

直接随波逐流一把梭就行,2024的国赛就考了这个加密

简单替换密码

加密时,每个明文都有自己对应的密文,而且不是简单的移位,是混乱的。

举个例子:

1
2
3
4
明文: abcdefghijklmnopqrstuvwxyz
密钥: phqgiumeaylnofdxjkrcvstzwb

a对应p,b对应h

一般用词频分析破解:http://quipqiup.com/

或者还是随波逐流一把梭

仿射密码

加密函数: \[ E(x)=(ax+b)\;mod \; m \] 其中,\(x\)是我们的原文,\(E(x)\)是我们的密文。\(a\)\(m\)必须满足: \[ gcd(a,m)=1 \]

\(m\)是我们整个仿射体系中的编码个数,为什么要互素呢?根据数论的知识不难得知,如果不互素的话,就找不到逆元了

那么,我们的解密函数也就很明显了: \[ D(x)=a^{-1}(x-b)\;mod \; m \] 其中,\(a^{-1}\)\(a\)的逆元

Playfair密码

原理:

  1. 选取一串英文字母,除去重复出现的字母,将剩下的字母逐个逐个加入 5 × 5 的矩阵内,剩下的空间由未加入的英文字母依 a-z 的顺序加入。注意,将 q 去除,或将 i 和 j 视作同一字。
  2. 将要加密的明文分成两个一组。若组内的字母相同,将 X(或 Q)加到该组的第一个字母后,重新分组。若剩下一个字,也加入 X 。
  3. 在每组中,找出两个字母在矩阵中的地方
    • 若两个字母不同行也不同列,在矩阵中找出另外两个字母(第一个字母对应行优先),使这四个字母成为一个长方形的四个角。
    • 若两个字母同行,取这两个字母右方的字母(若字母在最右方则取最左方的字母)
    • 若两个字母同列,取这两个字母下方的字母(若字母在最下方则取最上方的字母)

新找到的两个字母就是原本的两个字母加密的结果。

举个例子:

以 playfair example 为密匙,得

1
2
3
4
5
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 in the tree stump

1
HI DE TH EG OL DI NT HE TR EX ES TU MP

加密后密文:

1
BM OD ZB XD NA BE KU DM UI XM MO UV IF

加解密网站:http://www.metools.info/code/playfair_186.html

Polybius

ADFGX密码

Vigenere

Nihilist

Hill

Autokey Cipher

培根密码

栅栏密码

曲路密码

列位移密码

01248密码

JSFuck

BrainFuck

Ook

猪圈密码

舞动的小人密码

键盘密码

古埃及象形文字

宝可梦图腾

精灵语

古精灵语

夏多密码

圣堂武士密码

盲文

外星人密码

音乐密码

标准银河密码

天干地支表

摩斯密码

玛雅数字

原神密码