密码学-古典密码学

古典密码学分为替代置换两大类

键盘密码

运用键盘的布局等进行加密,位移等

布局形状

Tips:看键盘!

tgvhn uygbnjm uygbn yhnijm

flag:hack

坐标加密

35 16 13

flag:bye

这个我个人觉得脑洞有点大,基本不会出现,所以只展示两个给大家看看

凯撒密码

这是一种简单的位移密码,最标准的凯撒密码是位移3

示例密文eucmugcgu

flagkaisamima

只需要理解原理,可以使用解密工具进行解密即可

使用夺旗工具里面的CTF Crack

ROT13密码——凯撒密码的变体

和凯撒密码一样进行位移,但是一定是十三

示例密文URYYB

flagHELLO

只需要理解原理,可以使用解密工具进行解密即可

使用夺旗工具里面的CTF Crack

还有其他变体可能使用ASCII码进行变换迭代

频率密码

频率密码是根据单个字母出现的频率,对密码进行替换加密的方法

研究字母或者字母组合在文本中出现的频率。无论在何种自然语言体系当中,不同的文字单位都有其特定的出现频率,这个特征一般表现在长篇幅、有意义的文字序列中。以英文为例,出现频率最高的字母是e,其次是t、a、o…..

示例密文

Lw!

Gyzvecy ke WvyVKT!

W'zz by reso dsbdkwksky tzjq teo kly ujr. Teo keujr, gy joy dksurwmq bjdwv vorakeqojalr jmu wkd jaazwvjkwemd. Vorakeqojalr ljd j zemq lwdkeor, jzklesql gwkl kly juxymk et vecaskyod wk ljd qekkym oyjzzr vecazwvjkyu. Decy dwcazy ezu vwalyod joy kly Vjydjo vwalyo, kly Xwqymyoy vwalyo, kly dsbdkwkskwem vwalyo, glwvl wd klwd emy, jmu de em. Jzcedk jzz et klydy vwalyod joy yjdwzr boeiym keujr gwkl kly lyza et vecaskyod. Decy myg ymvorakwem cykleud joy JYD, kly vsooymk dkjmujou teo ymvorakwem, jzemq gwkl ODJ. Vorakeqojalr wd j xjdk twyzu jmu wd xyor wmkyoydkwmq klesql. De iwvi bjvi, oyju sa em decy veez vwalyod jmu ljxy tsm!

El jmu teo reso oyveoud cr mjcy wd WvyVKT{jzgjrd_zwdkym_ke_reso_dsbdkwksky_tzjqd}.

实用工具:https://www.quipqiup.com/

flagIceCTF{always_listen_to_your_substitute_flags}

摩斯电码

这是一种替换密码,看到题目后会辨认,然后知道如何解密即可

解密可以使用夺旗工具里面的CTF Crack

示例密文-- --- ... .. -.. .. .- -. -- .-

flagmosidianma

BrainF**k和Ook密码

主要是对程序源代码进行加密,把一些指令替换为其他符号

BrainF**k
+++++ +++[- >++++ ++++< ]>+++ +++++ .++++ +.--- -.<++ +[->+ ++<]> +.--- ----. <

Ook示例
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook! Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook? Ook! Ook. Ook? Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook.

Short Ook
..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... ..... !.... ..... ..!.! !!!!! !!!.? ..... ..!?! !.?.. ....? .?!.? ..!.! !!!!! !!!!! !!!!. ?.

flagHMISL

只需要知道这两个加密方式长什么样就行啦!然后使用解密工具即可

例如使用工具:https://ctf.bugku.com/tool/brainfuck

培根密码

一种简单的替换密码,密文只有两个字母组成,由五个字母来表达一个字母

例如h被替换为aabbb,因此,看到只有两个字母组成的密文,那么大概率是培根密码

示例密文aabbbaabaaababbababbabbbaaaaaababbaaaaaa

flaghelloawa

常规培根密码表ijuv对应密文相同

扩展培根密码表:包括了26个字母

扩展使用

那么既然我们可以把任意字符串转化为ab两种形式,那么我们也可以用ab来表示大写小写等

比如说iloveuctfailoveuctfailoveuctfailoveuctfa

通过a表示大写b表示小写的加密,例如aabbbaabaaababbababbabbbaaaaaababbaaaaaa

就可以变化为ILoveUCtFAIlOveUcTfaIlovEUCTFAiLovEUCTFA

那么用这段东西来表示培根密码的ab

这是一段示例的加密程序

package main

import (
    "fmt"
    "strings"
)

func main() {
    pattern := "aabbbaabaaababbababbabbbaaaaaababbaaaaaa"
    text := "iloveuctfailoveuctfailoveuctfailoveuctfa"
    var result strings.Builder

    for i, char := range text {
        if pattern[i] == 'a' {
            result.WriteRune(rune(strings.ToUpper(string(char))[0]))
        } else if pattern[i] == 'b' {
            result.WriteRune(rune(strings.ToLower(string(char))[0]))
        }
    }

    fmt.Println(result.String())
}

推荐解密网站:https://rumkin.com/tools/cipher/baconian/

也可以使用本地解密工具

仿射密码

仿射密码为单表加密的一种,字母系统中所有字母都藉一简单数学方程加密,对应至数值,或转回字母。它是一种替换密码,利用加密函数一个字母对一个字母的加密

加密函数是 E(x)= (ax + b) (mod m),其中,a和m互质,m是字符集的大小。
(例如,26即是以26个字母作为编码,当m是26时,a必须是1,3,5,7,9,11,15,17,19,21,23,25其中之一)

对应密码表

例题

假设密钥K= (7,3) 使用仿射密码体制加密单词hot并对得到的密文进行解密。

加密

加密函数: E(x)= (7x + 3) (mod 26)
根据上面英文字母编码表得到X

解密

求乘法逆元的方法

def extended_gcd(a, b):
    """
    扩展欧几里得算法
    返回整数 x 和 y,使得 ax + by = gcd(a, b)
    """
    if a == 0:
        return b, 0, 1
    gcd, x1, y1 = extended_gcd(b % a, a)
    x = y1 - (b // a) * x1
    y = x1
    return gcd, x, y

def mod_inverse(a, m):
    """
    计算 a 在模 m 下的乘法逆元
    """
    gcd, x, _ = extended_gcd(a, m)
    if gcd != 1:
        raise ValueError(f"{a} 和 {m} 不是互质,逆元不存在。")
    else:
        return x % m

# 示例
a = 7
m = 26

inverse = mod_inverse(a, m)
print(f"{a} 在模 {m} 下的乘法逆元是: {inverse}")

解密函数
求得a的乘法逆元为15
D(x) = 15(x - 3) (mod 26)

def extended_gcd(a, b):
    """
    扩展欧几里得算法
    返回整数 x 和 y,使得 ax + by = gcd(a, b)
    """
    if a == 0:
        return b, 0, 1
    gcd, x1, y1 = extended_gcd(b % a, a)
    x = y1 - (b // a) * x1
    y = x1
    return gcd, x, y

def mod_inverse(a, m):
    """
    计算 a 在模 m 下的乘法逆元
    """
    gcd, x, _ = extended_gcd(a, m)
    if gcd != 1:
        raise ValueError(f"{a} 和 {m} 不是互质,逆元不存在。")
    else:
        return x % m

def affine_decrypt(ciphertext, a, b, m):
    """
    解密仿射密码
    """
    # 求乘法逆元
    inv_a = mod_inverse(a, m)
    
    plaintext = ""
    for char in ciphertext:
        if char.isalpha():
            y = ord(char) - ord('A')
            x = inv_a * (y - b) % m
            plaintext += chr(x + ord('A'))
        else:
            plaintext += char
    return plaintext

# 示例
a = 7
b = 3
m = 26
ciphertext = "axg".upper()

plaintext = affine_decrypt(ciphertext, a, b, m)
print("解密后文本:", plaintext)

加解密工具:http://www.hiencode.com/affine.html

猪圈密码

替换式密码,非常简单

各种密码变通:https://blog.csdn.net/weixin_47869330/article/details/111396033

维吉尼亚密码

明文I love you

密钥abc

密文I mqvf aov

注意重复使用密钥进行加密,推荐解密工具:https://www.qqxiuzi.cn/bianma/weijiniyamima.php

栅栏密码

栅栏密码(Rail Fence Cipher)是一种置换密码,它将明文按照一定规则写入多个栅栏中,然后将栅栏中的字符逐行读取以加密消息。例如,使用3个栅栏(3行)的栅栏密码将明文Welcome to HMISL!!写成如下形式:

1 2 3 4 5 6
1 W c e H S !
2 e o t M L
3 l m o I !

得到密文:WooSecmtHIL!leM!

在线工具:https://ctf.bugku.com/tool/railfence

费纳姆密码

二战德军使用的密码,属于二进制运算密码

明文
HELLO=1001000 1000101 1001100 1001100 1001111
密钥
CRUDE=1000011 1010010 1010101 1000100 1000101
异或运算
密文:0001011 0010111 0011001 0001000 0001010

解算脚本,顺便了解GitHub的使用:https://github.com/0neOfU4/fenhum-decode

杰斐逊转轮加密

杰斐逊转轮加密器,这个装置由36片同样大小的木制转轮,套在一根杆上。每片转轮的圆周边缘上可有乱序26个英文字母表

通信双方必须各自拥有一套完全一样的转轮加密器。

加密方转动加密器上的转轮,是明文(不超过36字)正好出现在同一行上,这时转轮排列的其他25行都是无意义的乱码,把其中任意一行的乱码抄写来,得到密文。
接收方收到密文,转动加密器上的转轮,使得密文正好出现在同一行上,然后查看其他25行的内容,有意义的行就是明文。
杰斐逊加密器属于典型的“多表替换”加密(每一个转轮就相当于一个替换的字母表),他很难破解,除非能得到通信双方所使用的加密装置。

加密示例

1: <ZWAXJGDLUBVIQHKYPNTCRMOSFE <
2: <KPBELNACZDTRXMJQOYHGVSFUWI <
3: <BDMAIZVRNSJUWFHTEQGYXPLOCK <
4: <RPLNDVHGFCUKTEBSXQYIZMJWAO <
5: <IHFRLABEUOTSGJVDKCPMNZQWXY <
6: <AMKGHIWPNYCJBFZDRUSLOQXVET <
7: <GWTHSPYBXIZULVKMRAFDCEONJQ <
8: <NOZUTWDCVRJLXKISEFAPMYGHBQ <
9: <QWATDSRFHENYVUBMCOIKZGJXPL <
10: <WABMCXPLTDSRJQZGOIKFHENYVU <
11: <XPLTDAOIKFZGHENYSRUBMCQWVJ <
12: <TDSWAYXPLVUBOIKZGJRFHENMCQ <
13: <BMCSRFHLTDENQWAOXPYVUIKZGJ <
14: <XPHKZGJTDSENYVUBMLAOIRFCQW <

密钥:2,5,1,3,6,4,9,7,8,14,10,13,11,12
密文:HCBTSXWCRQGLES

具体的过程

先按密钥行排列

2: <KPBELNACZDTRXMJQOYHGVSFUWI <
5: <IHFRLABEUOTSGJVDKCPMNZQWXY <
1: <ZWAXJGDLUBVIQHKYPNTCRMOSFE <
3: <BDMAIZVRNSJUWFHTEQGYXPLOCK <
6: <AMKGHIWPNYCJBFZDRUSLOQXVET <
4: <RPLNDVHGFCUKTEBSXQYIZMJWAO <
9: <QWATDSRFHENYVUBMCOIKZGJXPL <
7: <GWTHSPYBXIZULVKMRAFDCEONJQ <
8: <NOZUTWDCVRJLXKISEFAPMYGHBQ <
14:<XPHKZGJTDSENYVUBMLAOIRFCQW <
10:<WABMCXPLTDSRJQZGOIKFHENYVU <
13:<BMCSRFHLTDENQWAOXPYVUIKZGJ <
11:<XPLTDAOIKFZGHENYSRUBMCQWVJ <
12:<TDSWAYXPLVUBOIKZGJRFHENMCQ <

再按密文调整每行顺序

2: <HGVSFUWIKPBELNACZDTRXMJQOY<
5: <CPMNZQWXYIHFRLABEUOTSGJVDK<
1: <BVIQHKYPNTCRMOSFEZWAXJGDLU<
3: <TEQGYXPLOCKBDMAIZVRNSJUWFH<
6: <SLOQXVETAMKGHIWPNYCJBFZDRU<
4: <XQYIZMJWAORPLNDVHGFCUKTEBS<
9: <WATDSRFHENYVUBMCOIKZGJXPLQ<
7: <CEONJQGWTHSPYBXIZULVKMRAFD<
8: <RJLXKISEFAPMYGHBQNOZUTWDCV<
14:<QWXPHKZGJTDSENYVUBMLAOIRFC<
10:<GOIKFHENYVUWABMCXPLTDSRJQZ<
13:<LTDENQWAOXPYVUIKZGJBMCSRFH<
11:<ENYSRUBMCQWVJXPLTDAOIKFZGH<
12:<SWAYXPLVUBOIKZGJRFHENMCQTD<

flag:XSXSBUGKUADMIN

解密代码

#秘钥
key="2,5,1,3,6,4,9,7,8,14,10,13,11,12"
#密文
cipher_text = "HCBTSXWCRQGLES"
  
  
f = open("zhuanlun.txt")
str_first_encry = []
  
  
for line in f:
    line = line.strip()
    str_first_encry.append(line)
  
  
key_index = key.split(",")
str_second_encry=[]
for k in key_index:
    str_second_encry.append(str_first_encry[int(k)-1])
    print(str_first_encry[int(k)-1])
  
  
for i,ch in enumerate(cipher_text):
    line = str_second_encry[i]
    split_index = line.index(ch)
    temp=[]
    temp[0:len(line)-split_index+1] = line[split_index:len(line)]
    temp[len(temp):] = line[0:split_index]
    str_second_encry[i] = "".join(temp)
print("-------------------------------------")
for plain in str_second_encry:
    print(plain)

zhuanlun.txt

ZWAXJGDLUBVIQHKYPNTCRMOSFE
KPBELNACZDTRXMJQOYHGVSFUWI
BDMAIZVRNSJUWFHTEQGYXPLOCK
RPLNDVHGFCUKTEBSXQYIZMJWAO
IHFRLABEUOTSGJVDKCPMNZQWXY
AMKGHIWPNYCJBFZDRUSLOQXVET
GWTHSPYBXIZULVKMRAFDCEONJQ
NOZUTWDCVRJLXKISEFAPMYGHBQ
QWATDSRFHENYVUBMCOIKZGJXPL
0WABMCXPLTDSRJQZGOIKFHENYVU
XPLTDAOIKFZGHENYSRUBMCQWVJ
TDSWAYXPLVUBOIKZGJRFHENMCQ
BMCSRFHLTDENQWAOXPYVUIKZGJ
XPHKZGJTDSENYVUBMLAOIRFCQW

棋盘密码

棋盘密码(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

密文就是字符在密码表里面对应的横纵坐标,如"a"加密为"11", “y"加密为"54”

Welcome to pangolin lab!
=>Polybius=>
52153113343215 4434 3511332234312433 311112!

ADFGX/ADFGVX密码

ADFGX/ADFGVX密码与棋盘密码原理相似,只是将行号和列号换成了ADFGX/ADFGVX字母,且表格内的字母顺序可以人为确定,ADFGVX密码比ADFGX新增了数字。下面是两个可能的密码表:

ADFGX:

A D F G X
A P H Q G M
D E A Y N O
F F L R C B
G D S T U V
X W Z X V I

ADFGVX:

A D F G V X
A P H 0 Q G M
D E A 1 Y N O
F 2 F L R C B
G 3 D S T U V
V W 4 Z 5 X 6
X 7 8 9 0 1 2