密码学,就是研究如何将一个内容(可以是字符串、文件、二进制流)通过一系列算法转换成另一种内容的学科。从广义上来看,有一个算法可以将字符串转换成另一个字符串即可,即该算法可逆不可逆都可以;从狭义上来看,该算法可以加密但同时需要解密。

不管你有没有专门学过密码学,我敢保证,你一定无时无刻不在接触它。举个例子,你开发的应用程序基本都会包含注册登录功能,而注册登录一般都会有“密码”字段,你将“密码”存入数据库时,都会调用加密算法;再比如,为了保证接口的安全性,你可能会提供“Token”字段,后台通过校验“Token”的合法性来判断当前接口请求者是否合法,这里的“Token”往往也会采用加密算法来生成。

如果你没有学过密码学,上述这些例子你只是在应用阶段,知道怎么调用前人已封装好的算法来加密你的数据。你可能会想,我知道一般的加密算法,我也知道怎么使用它,无需了解其底层原理,也不会影响我的应用安全,我也能保证应用安全。可事实真的是如此吗

这里我不妨给你做个假设。假设你不懂密码学,你只知道怎么使用加密算法来加密你的数据,会出现什么事呢?在某一天,因为某种原因,你存储在服务器的加密密钥被泄露了,黑客又知道你的系统是使用的何种加密算法,而加密算法一般是公开的,这时你的加密数据在黑客面前就变得透明;但如果你知道这些加密算法的底层原理,你就可以针对公开的加密算法来做微调,变成了你自己的加密算法,即使黑客知道你用的是何种加密算法,也无法在短时间内破解。

当然,上述例子可能会比较极端,但也不是没有可能。学好密码学,更重要的一点是更有助于你的职业发展。比如,你的老板让你开发一款安全级别要求很高的系统,需要你提供一套完整的加密方案,如果你不懂密码学,你就不知道怎么规划加密算法。我在这里提到的学习密码学,并不是说你能够自己设计一套加密算法,你只需要了解现有的常用加密算法的底层实现原理就够了

提到密码学,你可能首先会想到DES、AES、RSA等这些加密算法。没错,它们都属于密码学要学习的范畴。密码学是一个很宽泛的概念,要精通密码学需要很深厚的数学功底,本文也不会教你怎么实现自己的加密算法,但是会带你研究已公开的加密算法。

加密算法那按照年代可以分为古典密码和现代密码,按照密钥的对称方式可对称加密和非对称加密。当然,还有一些算法从狭义上来讲不属于加密算法,但是可以将其归为密码学的范畴,比如MD5、SHA1、Base64等。

本文我会带你了解古典密码学和Base64的算法原理。

古典密码学

密码学的出现最初是应用于军事上,如果你看过古装电视剧应该知道,在古代,人们传信一般通过飞鸽传书、鸿雁传书等方式。普通老百姓用明文来传递倒也没什么,如果在战争中,友军之间用明文来传书,中途被敌人拦截下来,后果将非常严重,很有可能就把本方的军事部署给泄露了。于是,人们想到了通过一些手段,将明文的内容转成密文,并在全军中通告解密方法。这样一来,即使敌人截获了情报,也无法获取有效的内容,这就是古典密码

古典密码不像现在的密码,运用了各种数学原理,它的算法也都比较简单,但也分了很多种。接下来,我将带你了解一些比较著名的古典密码。

 

凯撒密码

在古罗马,有一位非常著名的帝王--凯撒大帝。相传,凯撒大帝为了保护本方重要的军事信息,发明了一种加密方法,用于在军队之间传信,后人称其为凯撒密码

凯撒密码的算法非常简单,其基本方法为:将字母表A-Z和a-z按顺序排列,设定一个偏移值,比如设置为3,那么加密时对应位的字母依次向后偏移3位,比如字母A,偏移后的密文就是D,大小写要区分,如果为a,则偏移后为d。解密时,密文依次向前偏移3位即可。(注:如果向后偏移值超出后,又继续从第一个字母开始

凯撒密码只会加解密字母,遇到其他字符,则会明文输出。

思考:请用凯撒密码加密字符串:4fEdw2F(偏移值:5)

栅栏密码

栅栏密码,就是将明文分为N行(这里的N不固定),然后将字母在N行间交替输出,最后,将每行字母按顺序排列出来,就是密文。我描述的可能比较抽象,下面,我通过有一个实际的例子带你了解栅栏密码。

比如有一段文本:I Love You。我们分为两行(这里的N=2)如下:

I o e o

L v Y u

最后连成一行形成密文:IoeoLvYu。

解密时,将密文分为两行:

I o e o

L v Y u

最后上下交替输出,还原出明文:I Love You。

思考:请用栅栏密码加密字符串:The Dog is Cute。(N=3)

维吉尼亚密码

维吉尼亚密码由凯撒密码组成密码字母表,加解密时通过查询密码字母表得出明文和密文的映射关系。下图就是一种维吉尼亚密码字母表。

古典密码学原理和Base64算法原理-LMLPHP

其中,我们设定列代表明文,行代表密钥。

比如我们要加密字符串:YOUAREMYLOVE,密钥为ABCDE。明文为12个字符,密钥只有5个字符,因此需要将密钥补齐12位,补齐后的密钥为:ABCDEABCDEAB。从第一个字母Y开始,它对应的密钥为A,我们从密码字母表中找到A行Y列对应的字母为Y,第二个字母为O,密钥为B,找到B行O列的字母为P,依次类推,最终得到的密文为:BPWDVENAOSVF。

思考:请用维吉尼亚密码加密字符串:ILIKE(密钥为:YO)

 

曲路密码

曲路密码是一种换位密码,人们将它命名为曲路,原因就在于他的加密算法就像走一条曲路,双方约定好一条曲路(类似于密钥),加密时按照约定好的曲路来生成密文,解密时再逆向回推。

比如我们要加密一个字符串:The quick brown fox jumps over the lazy dog,按照5行7列的方式排成下列表格:

T

h

e

q

u

i

c

k

b

r

o

w

n

f

o

x

j

u

m

p

s

o

v

e

r

t

h

e

l

a

z

y

d

o

g

我们设定从上到下从左到右的曲路,如图:

古典密码学原理和Base64算法原理-LMLPHP备注:需要重新画图

最终,按照这种曲路生成的密文为:Tkoolavxbherjezyruoquwmtdohpnicfseg。

 

希尔密码

希尔密码是为数不多的运用了数学原理的古典密码算法,它利用了矩阵的基本原理。如果你学过线性代数,对矩阵应该不会陌生,在这里我假设你熟悉矩阵的运算。

希尔密码加密的基本思路是:将字母当成26进制数,如A=0,B=1,C=2以此类推,构建一个n维列向量,再同一个n*n的方阵相乘(相当于密钥),将结果模26,得出新的n维列向量,再按照26进制数转成字母即为加密后的密文。

这里需要注意的是,当且仅当n*n方阵可逆是,密文才能被解密,该矩阵可逆的充要条件是该矩阵对应的行列式与26互质。所谓两个数互质,即它们的公约数为1。

举个例子,加密字符串:BAT。先按照字母顺序构建3维列向量A= 古典密码学原理和Base64算法原理-LMLPHP ,再给定一3*3的方阵B= 古典密码学原理和Base64算法原理-LMLPHP (该矩阵对应的行列式为:441,他与26互质,该矩阵可逆,可以用于加密),两个矩阵相乘,B * A mod 26= 古典密码学原理和Base64算法原理-LMLPHP ,最后,将行向量的数字依次转化成字母得到密文:ZVT。

解密方法也很简单,首先找到n*n方阵的逆矩阵: 古典密码学原理和Base64算法原理-LMLPHP ,将逆矩阵与密文矩阵相乘,再模26即可得出明文。 古典密码学原理和Base64算法原理-LMLPHP

古典加密算法有很多种,本课程只讲解比较著名的古典密码,希望对你有所帮助。

通过对古典密码学的学习,是否对你有一定的启发,其实加密算法的核心就是将一个字符通过一些特定的操作转换成另外一个字符。

 

现代密码学

现代密码学产生于计算机发明之后,它同古典密码学不同,古典密码学大多是靠发明者的灵感和直觉,而现代密码学大量运用了数学公式、理论和计算机的二进制位运算。

现代密码学算法按照对称性又分为对称加密和非对称加密。对称加密,即用于加密和解密的密钥是使用的同一个密钥;非对称加密,即用于加密和解密的密钥不是同一个密钥,一般分为公钥和私钥,公钥用于加密,私钥用于解密。

现代加密算法中,我们熟知的对称加密算法有:DES,AES,XXTEA等;非对称加密算法有:RSA,DSA等。

其他密码学算法

本小节,我将给你讲解不属于上述范畴的,但从广义密码学来讲,也可以归结于密码学范畴的一个比较典型的算法--Base64编码。

你在开发中,或多或少都接触过Base64,很多语言都内置了Base64的算法,但是你是否了解其算法原理?本小节,我们带你深刻剖析Base64的底层原理。

Base64从字面上来看,最重要的就是64,即任何二进制内容通过Base64算法可以转换成只有64个字符组成的字符串。其基本思路是:将需要编码的内容转成二进制,然后每6位分隔,将二进制转成10进制,然后查询Base64码表,将对应的字符取出就是每个二进制位对应的Base64编码,如果分隔后位数不足6位用0补足,并且用”=“补齐4个字节。由于每个字符只有6位二进制,则二进制范围为000000-111111(0-63),共64个字符。标准的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

/

例1:将字符串BAT转成Base64编码。

首先,依次查询BAT对应的ASCII码表,得到对应的二进制数:

01000010 01000001 01010100

每6位分隔二进制,得出新的二进制组合:

010000 100100 000101 010100

将其分别转成10进制数:

16 36 5 20。

查询Base64码表可以得出该字符串编码为:QkFU。

例2:将字符串China转成Base64编码。

首先,依次查询China对应的ASCII码表,得到对应的二进制数:

01000011 01101000 01101001 01101110 01100001

每6位分隔二进制,得出新的二进制组合:

010000 110110 100001 101001 011011 100110 000100(不足位数用0补齐)

将其分别转成10进制数:

16 54 33 41 27 38 4

Q2hpbmE=(由于刚才补了两个0,所以需要添加一个”=“,如果补了4个0,则需要添加两个”=“)

解码时,逆向推导,即将编码后的字符串根据Base64码表从10进制依次转成二进制(位数为6),然后每8位分隔,查询ASCII码表即可得出明文。

以上就是Base64的详细算法,上述的Base64码表是标准的码表,如果你掌握了其原理,就可以开发一套Base64的变种算法,即将上述对应关系自定义设置,比如交换某些字符的顺序。这样,如果不知道这些对应关系就无法解码,从而一定程度上提升了系统安全。

思考:将字符串lagou转成Base64编码。

 

小结

本文首先给你介绍了古典密码学,通过一系列典型的古典加密算法,带你入门加密算法,虽然古典密码学现在已经不再使用,但是对于初学者学习加密算法有一定的帮助。除了详细介绍了古典密码学,我还分析了现代密码学的一些加密算法。

对于广义密码学来说,我还给你介绍了Base64编码,你只有掌握了Base64编码后,在应用开发中,对于编写更加安全的Base64编码将有极大的帮助。当然,Base家族还有Base32、Base16、Base58等,这些算法同Base64原理类似,只是包含的字符不同,你如果有兴趣可以执行研究,而我为你讲解Base64的原因在于Base64是应用最广泛的二进制编码算法。

还记得前面我给你留下的几个思考题吗?下面我就依次给出解释。

思考1:请用凯撒密码加密字符串:4fEdw2F。(偏移值:5)

凯撒密码只加密字母,数字原文打印,偏移值5即字母向后偏移5位,如果超出,则从第一个字母A/a继续开始,因此该字符串加密后为:4kJib2K。

思考2:请用栅栏密码加密字符串:The Dog is Cute。(N=3)

N=3表示将明文分为3行,即

T D i u

h o s t

e g C e

按行连接字符得出最终的密文:TDiuhostegCe

思考3:请用维吉尼亚密码加密字符串:ILIKE(密钥为:YO)

首先将密钥补齐为YOYOY,从维吉尼亚密码表按照密钥行明文列的方式得到最终的密文为:

GZGYC。

思考4:将字符串lagou转成Base64编码。

将字符串lagou通过查询ASCII码表查询其对应的二进制数为:

01101100 01100001 01100111 01101111 01110101

将二进制位按照6位为一组分隔:

011011 000110 000101 100111 011011 110111 010100(不足6位补0)

将每组二进制数分别转成对应的10进制数:

27 6 5 39 27 55 20

查询Base64码表,找到对应的字符,即为Base64编码的结果:

bGFnb3U=(由于后面补了2个0,则需要添加一个”=“)

09-09 12:24