网络安全| 十五种编码

306 阅读18分钟

原文链接:CTF密码学总结(一)-CSDN博客。本文在此基础上进行整理,主要是进行了分类,感谢原博主!

区分

  1. BASE64密码通常后面会有一个或者”==“

  2. Unicode 特征是以\u数字或者字母加数字

  3. URL编码 特征是%数字加字母,比如👉**%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C**,

    1. {的url编码是%7B,}的url编码是%7D
  4. 栅栏密码 栅栏密码潜规则,字符不会超过30个。

  5. 凯撒密码 好像还是全英文 特点:24个字母间的移动

  6. 摩斯密码(只有01(无规则)或.-,空格或/做分隔符)

  7. 如果是& # 类似符号,可以尝试 为 Unicode转ASCII

  8. 如果是一堆 /num这应该是ASCII 编码,需要用脚本变成字符

一.BASE64编码

BASE64编码中,特征和所拥有的字符字母:A-Z a-z;数字:0-9;符号:+ / ,然后末尾经常有一个“=”或者两个“==”。

原理,先把需要加密的字符串每个字符转换成ASCII码,然后ASCII码转换成二进制为8位二进制数字表示,然后在以六位二进制为一组转十进制,最后查找对应的BASE64对照表即可。

ASCII表,常用的无非就是大写字母和小写字母,大写字母的A开始是97,小写字母的a开始是65,推算下即可。

比如,这里需要加密“Ken”这个字符串,里面有大写和小写,查找ASCII码表,分别对应的是75 101 110,转换成二进制75:01001011; 101:01100101; 110:01101110;,先并排在一起,就是010010110110010101101110,然后在以六个为一组排序👉010010 | 110110 | 010101 | 101110,将这六个二进制重新转换成十进制,分别对应的是,18 54 21 46,然后对应base64码表,找出对应的上面重新转换成的十进制数字即可,分别是👉S2Vu,所以Ken这个字符串BASE64加密编码之后是S2Vu,如果不太清楚,看如下表格。

文本KenNULL
ASCII编码75101110NULL
二进制位010010110110010101101110NULL
分组010010110110010101101110
转换后的十进制&BASE64码表索引18542146
结果&Base64码表S2Vu

这样应该就差不多了,附上BASE64索引表,如下

数值字符数值字符数值字符数值字符
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P37f47v63/

ASCII

在附上一张ASCII码表图,如下图,图来自于网络。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sprNLZxb-1651127988009)(/images/wordimage/20220201/ASCII.jpg)]

1.有等号"="的情况

比如a这个字母,ASCII码是65,转换成二进制是01000001,转换成六个一组010000 | 01,就会发现后面不足以组成六位数,就可以在后面添零,就变成了👉010000 | 010000,转换成十进制就是16,然后根据BASE64码表对应的是Q,那么a的加密后就是QQ,但是我自己的理解是,加密后的长度也就是编码后的长度必须能整除4,才可以,这里QQ不能整除4所以不行,就可以加上=,长度就可以了,所以最终的编码就是QQ==

另外一种理解,如果要进行编码的字符串,不能被3整除,后面会多出一个字节或者两个字节,就可以使用“”来代替,比如编码a,不能被三整除,还差两位就可以被三整除,就可以在最终编码结果加上两个"",结合如下图理解更好。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crvj9qcO-1651127988010)(/images/wordimage/20220201/base64.png)]


二.base32加密

和base64加密差不多,这里直接举例子,先看下表是base32的索引表,比如这里我要BASE32编码,Ken,对应的ASCII码分别是,75 101 110,转换成二进制分别对应的是75:01001011; 101:01100101; 110:01101110,然后合在一起,是0100101101100101011011100,然后在以五个一组排序👉01001 | 01101 | 10010 | 10110 | 11100,然后在转换成十进制就是,9 13 18 22 28,根据下面的索引表,就是,JNSW4,这里只有五个数,必须要四个四个一组,不足四个就用=,来填充,所以就是JNSW4===

数值字符数值字符数值字符数值字符
0A9J18S273
1B10K19T284
2C11L20U295
3D12M21V306
4E13N22W317
5F14O23X
6G15P24Y
7H16Q25Z
8I17R262

可以看如下表格

文本KenNULLNULL
ASCII编码75101110NULLNULL
二进制位010010110110010101101110NULLNULL
分组0100101101100101011011100
分组后的十进制913182228
索引值JNSW4

三.base16加密

如果理解了,base64加密和base32加密方式,那么base16加密方式就很好理解了,先看如下base16索引表。

数值字符数值字符
0088
1199
2210A
3311B
4412C
5513D
6614E
7715F

先还是和base64和base32一样将需要加密的字符串转换成ASCII码然后转换成二进制,区别就是分组排序的时候是以4个为一组来排序,base64是六个为一组,base32是以五个为一组,如下图理解即可,图来自CSDN。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bdEzvPGC-1651127988011)(/images/wordimage/20220201/base16.png)]


四.Unicode编码

特征是以\u数字或者字母加数字,比如,\u6211,转换中文就是“我”,\u过后是每四个为一组,最简单解码方式可以使用python的print函数输出即可,编码👉**\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064**,解码效果如下图👇,成功解码出字符串Hello World

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rtB0wZbT-1651127988011)(/images/wordimage/20220201/unicode.png)]

上面是解密,加密如下。

编码原理,先将需要加密的字符转换成ASCII编码,然后把ASCII编码转换成十六进制即可,不足四位前面添0即可,比如a这个字符,编码之后是0x61,就需要加零就是0x0061,如下是python实现,非常简单。

最重要的就是ord函数和hex函数,ord函数把字符转ASCII,然后hex把数字转十六进制。

str='flag'
dict = []
for i in str:
    result = hex(ord(i)).replace(r'0x',r'\u')
    dict.append(result)
print("".join(dict))

五.URL编码

在浏览器地址栏经常能看见,特征是%数字加字母,比如👉**%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C**,这种类型的,解码之后的原文是,你好世界,还是需要用到python,当然也可以在线编码解码,需要用到的是python的urllib模块下面的parse模块,如下代码。

quote是编码

import urllib.parse as url
str = '你好世界'
print(url.quote(str))

输入效果如下

%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C

如何解码,如下python代码。

import urllib.parse as url
str = '%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C'
print(url.unquote(str))

解码效果为你好世界


六.进制转换

1.python实现进制转换


1.十进制转二进制

可以用到一个函数bin函数,可以之间转换,如下代码。

print(bin(10))

输出结果是0b1010


2.二进制转十进制

可以用到一个int函数,如下代码,int函数里面的2代表的是进制。

str = '1010'
print(int(str,2))

输出的数字是10


3.十进制转八进制

需要用到一个oct函数,如下代码。

print(oct(100))

输入结果是0o144


4.八进制转十进制

和上面二进制转十进制差不多,如下代码,只需要更改数字即可

str = '144'
print(int(str,8))

5.十进制转十六进制

需要用到一个hex函数,如下代码。

print(hex(255))

输出结果是0xff,十六进制转换十进制和上面差不多,只需要更改数字即可。


2.手算进制

可以直接参考百度百科👉进制转换


七.置换密码

1.加密

1.明文:State Key Laboratory of Networking and Switching

2.加密密钥:key=(1,5,6,2,3)

3.将明文分组,按照六个字母一组来分,总共可以分为七组,不足六个字母的可以用双方事先规定好的字符来填充比如空格,如下是分组过后的样子👇。

P = (StateK)(eyLabo)(ratory)(ofNetw)(orking)(andSwi)(tching)

4.对每组字符进行加密,根据加密密钥key,把每组的第1位字符放在第5位字符上面,第5位字符放在第6位字符上面,第6位字符放在第2位字符上面,第2位字符放在第3位字符上面,第3位字符放在第1位字符上面,这样排序即可,如下👇。

P = (aKttSe)(Loyaeb)(tyaorr)(Nwfeot)(kgrion)(dinSaw)(hgcitn)

最终密文就是aKttSeLoyaebtyaorrNwfeotkgriondinSawhgcitn


2.解密

解密需要的是把密钥给反向过来,原本的密钥是(1,5,6,2,3)需要逆置换变成(1,3,2,6,5),然后在按照加密的方法即可解密。


八.栅栏密码

栅栏密码潜规则,字符不会超过30个。


1.加密

假设明文是:THEREISACIPHER,然后根据上下上下排序,就是

T E E S C P E
H R I A I H R

最后连在一起就是TEESCPEHRIAIHR。

加密的另外一种方法,明文是THEREISACIPHER,先两个两个分一组,就是,TH ER EI SA CI PH ER

先取出第一个字母:TEESCPE
在取出第二个字母:HRIAIHR

最后连在一起即可。

所谓栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话。 不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。(一般不超过30个,也就是一、两句话) 传统栅栏密码(矩阵行列,密钥是行数): 假如有一个字符串:123456789 取字符串长度的因数进行分组,假如key=3 1 2 3 \分组情况,每三个数字一组,分为三组 4 5 6 7 8 9 然后每一组依次取一个数字组成一个新字符串:147258369 \加密完成的字符串


2.解密

加密密文:TEESCPEHRIAIHR

解密只需要将密文从中间分开,变位两行。(这个就看题目分成几组,就是几行)

T E E S C P E
H R I A I H R

最后在上下上下组合起来即可。

THEREISACIPHER


九.单表代换密码

假设明文是:helloWorld

假设密钥是:KENSSB,去掉重复的字母就是KENSB,然后按照字母顺序排列剩余的字母即可得到一个方阵表,如下表。

KENSB
ACDFG
HIJLM
OPQRT
UVWXY
Z

然后在从左边下边开始一直到右边排序,即可得到代换密文,代换密码表如下表所示。

明文字母ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字母KAHOUZECIPVNDJQWSFLRXBGMTY

然后按照,明文字母所对应的密文字母,找到排序即可,helloword加密之后的密文是CUNNQGQFNO


十.埃特巴什码

最后一个字母代表的十第一个字母,倒数第二个字母代表的十第二个字母,如下表所示。

明文字母ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字母ZYXWVUTSRQPONMLKJIHGFEDCBA

十一.凯撒密码

根据如下表排序,如下表是最基础的凯撒密码,就是往右移位,A对应的B,B对应的是C,比如明文是KEN,那么按照下表密文对应的就是LFO。

明文字母ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字母BCDEFGHIJKLMNOPQRSTUVWXYZA

python代码如下,1代表的是移位。

def caser():
    flag = 'HelloWorld'.upper()
    dict_txt = 'abcdefghijklmnopqrstuvwxyz'.upper()
    dec = []
    for i in flag:
        dec.append(dict_txt[dict_txt.index(i)+1])
    print("".join(dec))
if __name__ == '__main__':
    caser()


十二.仿射密码

原理是,先将26个字母按照0-25排序也就是(0,1,2,3…25),密钥为k(a,b),加密公式为c=Ea,b(m)≡am+b(mod26),解密公式为m=Da,b(c)≡a-1(c-b)(mod26)

如下表是字母索引表

ABCDEFGHIJKLMNOPQRSTUVWXYZ
012345678910111213141516171819202122232425

1.加密

例如我这里要加密helloworld加密过程并且密钥是k(7,21):

h=7,7*7+21(mod26)=18,h=s

e=4,7*4+21(mod26)=23,e=x

l=11,7*11+21(mod26)=20,l=u

l=11,7*11+21(mod26)=20,l=u

o=14,7*14+21(mod26)=15,o=p

w=22,7*22+21(mod26)=19,w=t

o=14,7*14+21(mod26)=15,o=p

r=17,7*17+21(mod26)=10,r=k

l=11,7*11+21(mod26)=20,l=u

d=3,7*3+21(mod26)=16,d=q

所以helloworld加密之后的成果是sxuuptpkuq


2.解密

知道解密公式是m=Da,b(c)≡a-1(c-b)(mod26)&m=D7,21(c)≡7-1(c-21)(mod26) ,密文是sxuuptpkuq,解密过程如下。

s=18,7^-1*(18-21)(mod26)

x=23,7^-1*(23-21)(mod26)

省略。。。。


3.python代码

如下是加密代码。

def affine_cipher_en():
    flag = input('请输入你要加密的明文:')
    k_a = int(input("请输入密钥中的第一个值a:"))
    k_b = int(input("请输入密钥中的第一个值b:"))
    flag_list = list(flag.lower())
    flag_en = []
    for i in flag_list:
        flag_en.append(chr(((k_a * (ord(i)-97) + k_b) % 26)+97))
    print(''.join(flag_en))
affine_cipher_en()

如下是python解密代码

#解密脚本
def affine_cipher_de():
    flag = input('请输入你要解密的明文:')
    k_a = int(input("请输入密钥中的第一个值a:"))
    k_b = int(input("请输入密钥中的第一个值b:"))
    flag_list = list(flag.lower())
    flag_de = []
    for i in flag_list:
        flag_de.append(chr((15 * (ord(i) - 97 - k_b)) % 26 + 97))
    print(''.join(flag_de))



十三.棋盘密码

棋盘密码就是将26个字母放在5x5的方格子里面,ij放在一个格子里面,具体如下表👇。

12345
1abcde
2fghi/jk
3lmnop
4qrstu
5vwxyz

其中特点就是每两个数字编做一组,所有的数字都在1-5之间浮动,并且是先列后行的顺序排序。

比如25 15 33,所对应的就是Ken


十四.普莱费尔密码

假设密钥是kensb,那么排序之后如下表,前面和单表代换一样,假设明文是stegab

kensb
ACDFG
HI/JLMO
PQRTU
VWXYZ

加密原理就是如果假设需要加密明文里面的s对应的是p1,t对应的是p2,

1.那么p1,p2在同一行则对应的密文就是紧靠p1,p2右端的字母。

2.如果p1,p2在同一列则对应的密文分别是仅靠p1,p2下端的字母。

3.如果p1,p2不在同一列也不再同一行,那么对应的密文应该是p1,p2为对角顶点确定的矩阵的另外的两个顶点字母,按照同行原则对应。

加密效果如下表。

stegab
FYBCGK

解密就是加密过程。


本文转自 blog.csdn.net/kengkeng123…,如有侵权,请联系删除。

十五.转轮机加密

指解密中密文涉及转轮机加密,转轮机密文的特点是等长的分好组的乱序字母,原理是转齿轮把一个字母换成另一个来拼成一句话,所以会有多组密钥,但是只有一组密文。

比如

1:  < ZWAXJGDLUBVIQHKYPNTCRMOSFE <
2:  < KPBELNACZDTRXMJQOYHGVSFUWI <
3:  < BDMAIZVRNSJUWFHTEQGYXPLOCK <
4:  < RPLNDVHGFCUKTEBSXQYIZMJWAO <
5:  < IHFRLABEUOTSGJVDKCPMNZQWXY <
6:  < AMKGHIWPNYCJBFZDRUSLOQXVET <
7:  < GWTHSPYBXIZULVKMRAFDCEONJQ <
8:  < NOZUTWDCVRJLXKISEFAPMYGHBQ <
9:  < XPLTDSRFHENYVUBMCQWAOIKZGJ <
10: < UDNAJFBOWTGVRSCZQKELMXYIHP <
11: < MNBVCXZQWERTPOIUYALSKDJFHG <
12: < LVNCMXZPQOWEIURYTASBKJDFHG <
13: < JZQAWSXCDERFVBGTYHNUMKILOP <

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

密钥就是新的顺序,比如第一行是原来的第二行,第二行是原来的第三行

1-2:  < KPBELNACZDTRXMJQOYHGVSFUWI <
2-3:  < BDMAIZVRNSJUWFHTEQGYXPLOCK <
3-7:  < GWTHSPYBXIZULVKMRAFDCEONJQ <
....

轮转机密码密文对应的是每行字符串的第一列,所以我们将每一行的第一个字母对应到密文,此时是将字符向左转,将所有列的字符串写出,根据提示信息是指第二次大战期间,找到第18列字符串与题目信息相关,于是判定为flag

NACZDTRXMJQOYHGVSFUWIKPBEL
FHTEQGYXPLOCKBDMAIZVRNSJUW
....

然后第一列就是对应密文,第18列试试FIREINTHEHOLE,对应二战即结果

十六. 培根密码(大小写的ABab,而且必须是5个一组,不是5个就考虑摩斯密码):

培根所用的密码是一种本质上用二进制数设计的,没有用通常的0和1来表示,而是采用a和b

密码学脚本类总结:

ASCII转字符脚本:

指解题中遇到长串ASCII码形式,需要转字符,但是一个个转太麻烦,又没有在线的长串ASCII码转字符网站。且给出的长串ASCII码的间隔依情况而定,如:/119/101/,这时需要自己根据对应间隔写出批量转换脚本。

源代码修改逻辑解密:

指解题中在有较完整源代码的情况下代码逻辑比较明朗,且可以逆向。这时需要充分利用有源代码的优势来在源代码中修改处逆向逻辑,不要自己从头到尾另写一份。


版权声明:本文为CSDN博主「沐一 · 林」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/xiao__1bai/…