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

(密碼學是研究如何隱密地傳遞信息的學科。通過本課程實驗掌握密碼學的相關知識。)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM