crypto必知必会

时间:2023-03-08 16:26:20

crypto必知必会

最近参加了个ctf比赛,在i春秋,南邮方面刷了一些crypto密码学题目,从中也增长了不少知识,在此关于常见的密码学知识做个小总结!

Base编码

Base编码中用的比较多的是base64,首先就说一下Base64编码方式

  1. 将字符串以字节的方式进行分组,每三个字节一组,每组共24个二进制位。(不满3个字节的用‘=’填充)
  2. 对以上的分组,每一组又分为4个小组,即24bits分为4小组,每小组6个bits。
  3. 对每小组前加上00,将其拓展成32个二进制(4个字节)
  4. 每小组将其转化为ascii字符,根据以下图表进行转换

base64转换表

码值 字符   码值 字符   码值 字符   码值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

用处: 一般不用于加密,主要把二进制数转成普通字符串进行网络传输,因为某些二进制字符在传输协议属于控制字符,不能直接传输。

而base32与base64类似。

base32转换表

RFC 4648 Base32 字母表
符号 符号 符号 符号
0 A 8 I 16 Q 24 Y
1 B 9 J 17 R 25 Z
2 C 10 K 18 S 26 2
3 D 11 L 19 T 27 3
4 E 12 M 20 U 28 4
5 F 13 N 21 V 29 5
6 G 14 O 22 W 30 6
7 H 15 P 23 X 31 7
填充 =

Base32将任意字符串按照字节进行切分,并将每个字节对应的二进制值(不足8比特高位补0)串联起来,按照5比特一组进行切分,并将每组二进制值转换成十进制来对应32个可打印字符中的一个。

base16转换表

Base16 编码表
编码 编码
0 0 8 8
1 1 9 9
2 2 10 A
3 3 11 B
4 4 12 C
5 5 13 D
6 6 14 E
7 7 15 F

Base16编码使用16个ASCII可打印字符(数字0-9和字母A-F)对任意字节数据进行编码。Base16先获取输入字符串每个字节的二进制值(不足8比特在高位补0),然后将其串联进来,再按照4比特一组进行切分,将每组二进制数分别转换成十进制,在下述表格中找到对应的编码串接起来就是Base16编码。可以看到8比特数据按照4比特切分刚好是两组,所以Base16不可能用到填充符号“=”。

需要注意的是Base各种编码秘文的区分。

比如base16没有F之后的字母以及没有[a-zG-Z],base32没有[a-z0-1+/],快速区分base编码有助于解码。

python3里实现base64加解密有 base64.b64decode()等各种方法。

RSA解密

关于RSA加密原理请看这里传送门:RSA算法原理(一)

以及RSA简单理解请看这里传送门:RSA算法原理(二)

这里我简单说说CTF题目中的RSA

一般RSA题目会给出n,e,c,有时候也会给出p,q(c一般就是指密)

一般计算过程是先计算phi,有了phi和e可以求出d(密钥)再根据c,d,n就可以求得明文!

具体python3实现代码(需要安装第三方库gmpy2)

import gmpy2
import binascii
n =
p =
q =
c =
e =
phi = (p-1) * (q-1)
d = gmpy2.invert(e, phi)
n = p * q
print(pow(c, d, n))
print(binascii.a2b_hex(hex(pow(c, d, N))[2:]))

不过很多时候会只给出n而没有给出p,q这种情况要求通过n而求出q和p。这里提供一个可以分解n的网站

而且要注意e=1或者2,3这种情况,仔细看传送门:RSA算法原理(二)你会发现如果e=1,明文plain = c + n*k(k=0,1,2,3....),这种情况在题目中也遇到过,要注意!

恺撒密码

基本思想: 通过把字母移动一定的位数来实现加解密。如果移动的位数是13,加解密的算法一样。如下一个简单demo。

# -*- coding: utf-8 -*-
from string import ascii_uppercase, ascii_lowercase
__author__ = 'lateink'

cryptoMessage = 'synt{5pq1004q-86n5-46q8-o720-oro5on0417r1}'

message = ''

for i in cryptoMessage:
    if i in ascii_uppercase:
        x = (ord(i) - ord('A') + 13) % 26
        message += chr(x + ord('A'))
    elif i in ascii_lowercase:
        x = (ord(i) - ord('a') + 13) % 26
        message += chr(x + ord('a'))
    else:
        message += i

print(message)

变异恺撒

变异恺撒并不是简单把字母移动一定的位数,而是每个字母根据密码字典进行加密,这种必须要有密码字典才能解密。如果没有密码字典,如果爆破的话,数量级大概是26!但是一般情况并不会真的通过爆破去获取密码字典。一般密文是英文单词,而英文单词的话,可以通过词频分析这攻击手段破解。这里提供一个词频分析解密网站quipquip.

奇偶位变化

恺撒密码中有一种套路是,字符串的奇数位加,偶数位减(或者相反),如果解密过程中没什么头绪的时候不妨试试这种方式。

md5

md5采用hash算法加密数据,不可逆,不能从密文推算出明文。有些网站提供md5解密,大概都是使用一个比较大密码字典爆破md5密文,搜索密码字典里是否有对应的密码加密后与要解密的密文相等。感觉没啥用。

密文特征

32个或者16个16进制字符串

其他奇奇怪怪的加密

猪圈密码

{ 'a': 'j', 'b': 'k', 'c': 'l', 'd': 'm', 'e': 'n', 'f': 'o', 'g': 'p', 'h': 'q', 'i': 'r',

's': 'w', 'v': 'z', 't': 'x', 'u': 'y'

}

猪圈密码就是根据上面密文字典加解密

异或

ctf题中还有一种常见的密文解密是用到疑惑,需要明文和密文异或才能得到一串有意义的字符串。

目前遇到的CTF中所需要的加解密总结大致如此,之后遇到新的问题新的套路再更新

continue updating...