关于密码学:密码学入门

44次阅读

共计 14915 个字符,预计需要花费 38 分钟才能阅读完成。

原创:打码日记(微信公众号 ID:codelogs),欢送分享,转载请保留出处。

简介


在信息安全畛域,个别会遇到 ” 窃听 ”、” 篡改 ”、” 假装 ”、” 否定 ” 这些威逼,而明码学家们提供了相应的密码学算法来解决这些问题,如下:

  • 窃听:攻击者能够在网络上安置了一个路由器,侦听所有通过的数据包,这样数据就被泄密了,密码学提供了对称明码与公钥明码算法对数据加密,保障机密性。
  • 篡改:攻击者对通过的数据包进行批改,使得接管方获取到谬误的信息,密码学提供了单向散列函数生成“数据指纹”,保障数据完整性。
  • 假装:攻击者伪装成发送方来发送数据,使得接管方获取到虚伪的信息,密码学提供音讯认证码生成 ” 认证码 ”,保证数据起源的正确性。
  • 否定:发送方自身是攻击者,发送了歹意申请后,谎称本人没有发此申请,密码学提供了数字签名算法,使其不可否认。

像对称加密、公钥加密、音讯散列、音讯认证码、数字签名这些算法,也被称为明码学家的工具箱。

加密分类

现如今的加密算法,次要分为两大类,一类是对称加密,而另一类是非对称加密,而对称加密在实现形式上又能够分为两类,一类是分组加密算法,另一类是流加密算法。

分组加密

分组加密(block cipher),每次加密或解密数据中特定长度的一小块,前一块解决完了再解决下一块,直到所有数据都解决完,这里的“一块”就称为分组,而一个分组的 bit 数就是分组长度。

常见的分组加密算法有 DES 与 AES,比方 DES 的分组长度是 64bit,而 AES 的分组长度能够是 128bit 或 192bit 或 256bit,因为 DES 或 AES 的算法过程比较复杂,暂不介绍,但咱们有必要理解一下它们常常应用的根底运算 XOR。

XOR 加密

在位运算中,个别有 AND(与)、OR(或)、NOT(非)运算,然而还有一种位运算也十分罕用,即 XOR(异或),它的运算规定如下:

简略来说,就是两边雷同后果是 0,两边不同后果是 1,所以才称为“异或”嘛!

而如果将 XOR 运算利用在多 bit 的数据上,咱们会发现 XOR 有十分好的自反个性,如下:

  1. 数据 A 与 B 异或之后,变成了一个新数据
  2. 而当咱们将新数据再与 B 异或运算后,发现它又变成了 A!
  3. 从而,咱们惊奇的发现,如果把 B 看成是密钥的话,XOR 能够用来实现加密、解密算法,而加密、解密过程,都只须要数据与密钥做 XOR 运算即可。

Linux 命令做 XOR 加密

$ pip install xortool

# 明文文件,内容是 hello
$ echo -n hello > plain.txt

$ xxd plain.txt
00000000: 6865 6c6c 6f                             hello

# 用 xor 算法加密,明码为 pass,生成 encrypt.bin
$ cat plain.txt | xortool-xor -n -r pwd -f - > encrypt.bin

$ xxd encrypt.bin
00000000: 1812 081c 18                             .....

# 用 XOR 算法解密,可还原成明文
$ xortool-xor -n -r pwd -f encrypt.bin
hello

尽管对称加密算法的外围是 XOR,但如果加密算法只应用 XOR 的话,其加密的强度并不够高,很容易被破译或泄密。

上面会以一个故事开展密码学的各种算法概念及用处,背景如下:
男主:小李 ,女主: 小红 ,男配: 大李 ,小李的哥哥,女配: 小美 ,小红的闺蜜
小李与小红是同班同学,业余计算机,小李对小红爱慕已久!

恋爱日记:小李写情书

为了表白倾慕之情,小李写了一封情书,写了好长时间,决定发给小红,但又不想被网络上的其他人看到!如下:

因为小李最近学习了 XOR 加密算法,于是应用 XOR 加密了情书,如下:

cat plain.txt | xortool-xor -n -r pwd -f - > encrypt.bin


能够看到,加密后的数据都是乱码了,成果很好!

小李叫苦不迭,将本人的成绩展现给哥哥大李看!大李指出,这样的加密算法强度不够高,明码学家们能够轻易破解,开始给小李展现破译过程!

# 统计原文词频
$ grep -oP . plain.txt |sort|uniq -c|sort -nr|head
     66,37 你
     31 的
     25 我
     15 是
     15 不
     13 一
     12 想
     10 会
      9 都

# 统计密文词频
$ xxd -g3 -c3 -ps encrypt.bin |sort|uniq -c|sort -nr|head
     66 9fcbe8
     37 94cac4
     31 97ede0
     25 96fff5
     15 96efcb
     15 94cfe9
     13 94cfe4
     12 96f4d7
     10 94cbfe
      9 99f4d9

# 按词频结构替换表
$ paste <(xxd -g3 -c3 -ps encrypt.bin |sort|uniq -c|sort -nr|head|awk '{print $2}'|sed -E 's/../\\x&/g') <(grep -oP . plain.txt |sort|uniq -c|sort -nr|head|awk '{print $2}')
\x9f\xcb\xe8,\x94\xca\xc4    你
\x97\xed\xe0    的
\x96\xff\xf5    我
\x96\xef\xcb    是
\x94\xcf\xe9    不
\x94\xcf\xe4    一
\x96\xf4\xd7    想
\x94\xcb\xfe    会
\x99\xf4\xd9    都

# 变成 sed 替换脚本
$ paste <(xxd -g3 -c3 -ps encrypt.bin |sort|uniq -c|sort -nr|head|awk '{print $2}'|sed -E 's/../\\x&/g') <(grep -oP . plain.txt |sort|uniq -c|sort -nr|head|awk '{print $2}') | awk '{printf"s/%s/%s/g; ",$1,$2}'
s/\x9f\xcb\xe8/,/g; s/\x94\xca\xc4/ 你 /g; s/\x97\xed\xe0/ 的 /g; s/\x96\xff\xf5/ 我 /g; s/\x96\xef\xcb/ 是 /g; s/\x94\xcf\xe9/ 不 /g; s/\x94\xcf\xe4/ 一 /g; s/\x96\xf4\xd7/ 想 /g; s/\x94\xcb\xfe/ 会 /g; s/\x99\xf4\xd9/ 都 /g;

应用 sed 将密文依照替换表进行替换,如下:

能够发现,一部分信息被还原回来了!

大李说,尽管 XOR 应用明码对数据每字节进行异或后,实现了加密,但它相当于是一种替换表,每组确定的明文被替换为确定的密文,然而人类的文章大多是有统计特色的,比方在中文里 ”“,”“ 之类的字 呈现频率就很高 ,黑客收集了大量人类文字且统计出 字频表,因此只有将密文中呈现频率高的密文替换为字频表中的明文,而后连懵带猜就能够破译出密文信息了。

为了激进小李的机密,大李帮小李应用 AES 算法将情书加密,而后发给了小红 …

恋爱日记:小红回应情意

小红收到情书后,十分打动,为表白本人的情意,小红自拍了一张照片,修了好长时间,想发给小李,但同时又不想被其他人看到!

小红也理解到 XOR 能够进行加密,于是应用 XOR 算法对照片进行了加密,如下:

# bmp 图片前 54 字节是图片元数据,这部分要放弃不变
(head -c 54 image.bmp;tail -c +55 image.bmp| xortool-xor -n -r password -f -) > image2.bmp 

当加密实现后,小红关上照片,发现照片的确不一样了,但还是能看出本人的大抵模样。

小红心想,不行,加密算法还得再改改,这样熟人还是能认出我来!为了解决这个问题,小红同样打算应用明码学界广为流传的 AES 算法试试!

AES-ECB 加密

小红找到了如下的代码,而后对图片加了密,如下:

(head -c 54 image.bmp;tail -c +55 image.bmp| openssl enc -aes-128-ecb -e -in - -out - -k password) > image3.bmp 


能够看到,AES 算法很优良,加密后的图片,曾经齐全看不清模样了,只能看到大抵轮廓!

尽管这张照片已齐全认不出是小红了,但小红心里还是有点疙瘩,这图片还是有点裸露了我的身材啊!

AES-CBC 加密

通过一段时间搜寻,小红发现 AES 还有其它的加密模式,如 CBC,于是应用 CBC 模式试了下,如下:

(head -c 54 image.bmp;tail -c +55 image.bmp| openssl enc -aes-128-cbc -e -in - -out - -k password -iv 0102030405060708) > image4.bmp 


太棒了!小红差点叫出声来,加密后的照片像收不到信号的黑白电视机一样,小红自已都不意识自已了,小红称心的笑了笑,将照片发给了小李。

加密模式

如上过程一样,为了使对称加密算法更牢靠,明码专家们玩出了一些新花样,咱们称其为加密模式,常见的加密模式有 ECB、CBC、CFB、CTR、OFB 等,这里仅筛选 ECB 与 CBC 介绍一下,如下:
ECB 模式
ECB 模式的全称是电子密码本模式(Electronic CodeBook),在 ECB 模式中,每个明文分组加密后,间接作为密文分组输入,如下:

这种模式其实和下面的 XOR 加密算法一样,每一小块数据,都应用雷同的密钥和形式进行加密,所以这也解释了为啥图片加密后还能看到轮廓,因为密钥在每一小块上的扰乱成果是整齐划一的,当图片很大时,从宏观上会透出大量信息进去。

一般来说,当初已不倡议再应用 ECB 模式加密数据了。

CBC 模式
CBC 模式全称是密文分组链接模式(Cipher Block Chaining),之所以叫这个名字,是因为密文分组像链条一样相互连接在一起。

能够发现,CBC 模式很奇妙,它将前一组加密产生的密文分组,参加到下一组的加密过程中去了,用后面的数据扰乱前面的数据!

实际上分组加密的过程,能够设想成在图片上撒沙,其中图片就是期待加密的数据,而密钥则是沙。
对于 ECB 模式,就是每个区域撒上雷同散布的沙,而对于 CBC 模式,则是每次撒的沙会变花色。

初始化向量

能够发现,在应用 CBC 模式时,须要一个初始化向量 IV,其实它就是一个分组长度的随机 bit 序列,用来加强第一个分组的加密成果,那它有什么作用呢?

咱们有时候也称初始化向量为盐 (Salt),它的作用就像盐一样,扰乱加密后的数据,如果你应用的 128bit 密钥很简略,这时明文的前 128bit(第一个分组) 加密成果就会很差,这个分组很容易被破译,而有了初始化向量后,因为初始化向量是随机的,这会导致第一个分组也会被烦扰地面目全非。

应用初始化向量还有一个益处,二次加密过程,就算是应用雷同的密钥,加密进去的密文也不一样。

有个疑难是,如果解密方没有初始化向量,根本无法解密啊!

是的,所以初始化向量须要通知解密方,一种办法是每一次加密时生成初始化向量,并将初始化向量拼接在密文结尾,是的,初始化向量并不是密钥,没有窃密需要,间接附在密文中也没有关系。

填充模式

分组加密算法中还有一部分就是填充算法,如 NoPadding, PKCS#5, PKCS#7, ISO 10126, ANSI X9.23 和 ZerosPadding 等。

为什么会须要填充算法呢?这是因为分组加密算法是一组一组加密的,比方分组大小是 128bit 的话,如果明文数据最初一组有余 128bit,该怎么办呢?这时就须要填充算法了,而 PKCS#7 算法是目前应用得最宽泛的填充算法了。

所以,在 Java 中要应用 AES 对数据进行加密时,应传递的算法名称为 AES/CBC/PKCS5Padding,其中 AES 是算法,CBC 是加密模式,而PKCS5Padding 就是填充模式,而 PKCS5Padding 实际上就是 blockSize=8bytesPKCS#7

pkcs5 与 pkcs7 区别:https://www.cnblogs.com/midea…

流加密

流加密(stream cipher),是对数据流进行间断解决的一类明码算法。流明码中个别以 1bit、8bit 或 32bit 等为单位进行加密和解密。

常见的流加密算法有 RC4、A5 等,尽管它们也是对称加密算法的一类,但目前来说,分组加密算法应用得更为宽泛一些,因而不做过多介绍。

非对称加密

非对称加密,又称公钥加密,应用非对称加密算法,须要生成一对密钥,公钥与私钥,而后加密方应用公钥进行加密,而解密方应用私钥进行解密。

  • 私钥:是须要本人保留的私密密钥,不能让他人晓得的。
  • 公钥:能够公开给公众应用,以使他们能够和本人通信。

就像客户端与服务器模式一样,多个客户端领有公钥,客户端应用公钥加密数据后发送给服务端,而加密后的数据只有持有私钥的服务器才能够解密进去。

注:实际上也能够应用私钥来加密,应用公钥来解密,前面介绍的数字签名技术,会应用这种办法。

RSA

RSA 是应用最宽泛的公钥算法,在 1977 年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。过后他们三人都在麻省理工学院工作。RSA 就是他们三人姓氏结尾字母拼在一起组成。

RAS 理论加解密过程很简略,都是对数据进行乘方运算后取模,如下:
加密:密文 = 明文 ^ E % N,其中 E、N 就是两个数字
解密:明文 = 密文 ^ D % N,其中 D、N 就是两个数字
其中 (E,N) 组合在一起为公钥,(D,N)组合在一起为私钥,如下,假如 E =5,N=323,D=29,能够发现 234 通过 RSA 加密后变成 81、RSA 解密后还原成了 234:

$ bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
234^5%323
81
81^29%323
234

当然 E、N、D 不是轻易得来的数字,它们是依据一系列数学过程计算而来的,有着隐含的数学关系,因而 RSA 还设计了一套密钥对生成算法,用以生成 E、N、D 这 3 个数字。
对于密钥对生成细节,以及 RSA 加解密在数学上的证实,这里不再赘述,能够参考阮一峰的解析:
https://www.ruanyifeng.com/bl…
https://www.ruanyifeng.com/bl…

非对称加密算法,除了 RSA 以外,还有如 ElGamal、Rabin、ECC 等,一般来说,非对称加密算法都是基于数学难题来实现的,比方 RSA 基于大数质因数分解难题。
而且非对称加密算法还有一个特点,就是加密后的数据,本人都无奈解密,只有持另一个密钥的人才能解密。

模运算

RSA 的数学原理比较复杂,但咱们能够简略的认为,RSA 加密后的密文,之所以可能解密,次要奉献是模运算,能够通过简略的同余定理来了解,如下:
同余 :如果 p , c 对 m 求模后失去的余数雷同,则称模 m 与 p、c 同余。
在同余运算规定中,有一个 同余式相加 运算,如下:
(A+B)%C = (A%C + B%C)%C
假如 C =256(1 字节大小),利用此规定,能够失去如下演算过程:

  1. 将 x 看作 A,127+129 作为整体看作 B,失去:
    (x + 127 + 129) % 256 = (x % 256 + (127 + 129) % 256) % 256 = x % 256
  2. 将 x +127 作为整体看作 A,将 129 看作 B,失去:
    (x + 127 + 129) % 256 = ((x + 127) % 256 + 129 % 256) % 256 = ((x + 127) % 256 + 129) % 256
  3. 由 1, 2 可失去:
    x % 256 = ((x + 127) % 256 + 129) % 256
  4. 当 x 小于 256 时,可失去:
    x % 256 = x,所以 x = ((x + 127) % 256 + 129) % 256
  5. 因而,可失去一个非对称加密算法如下:
    加密:(x + 127) % 256 = S (密文)
    解密:(S + 129) % 256 = ((x + 127) % 256 + 129) % 256 = x (明文)

其中,公钥是(127,256),私钥是(129, 256),这个加解密过程看起来是不是和 RSA 很像?只不过 RSA 用的是模幂运算,而这里应用的是简略的相加求模运算!

能够把基于模运算的加解密,看作是在转圈圈,起始明文在如下地位:

通过加密之后,跑到快半圈,到了 160(密文)的地位,如下:

再通过解密之后,跑完了 1 整圈,又回到了 33(明文)的地位,如下:

当然,这个非对称加密算法并不平安,如下:

  1. 这个算法只跑 1 圈就回到明文了,很容易依据密文法则推算出明文,而 RSA 算法加解密都是用的模幂运算,会跑很多圈,所以破解难度很大,数学上称为离散对数难题。
  2. 这个算法公钥与私钥之和就是一圈,依据公钥很容易推算私钥,但 RSA 算法公钥与私钥的隐含数学关系更简单,要想通过公钥推算私钥,须要解决大数质因数分解难题。

Linux 工具命令

# 生成私钥与公钥
openssl genrsa -out rsa_private_key.pem 2048 
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout 

私钥与公钥是由数字 E、N、D 组成的,如下可查看私钥、公钥文件中这些数字的值:

# 读取私钥信息
$ openssl rsa -in rsa_private_key.pem -text -noout
RSA Private-Key: (2048 bit, 2 primes)
modulus:
    00:d1:ca:47:3a:c5:34:b1:2f:4e:f0:a7:29:0d:99:
    de:51:89:ae:1c:1f:81:22:53:7c:fe:c1:68:62:80:
    ...
publicExponent: 65537 (0x10001)
privateExponent:
    00:cb:f3:8b:d5:fd:dc:61:19:2d:f4:55:7e:5a:c3:
    a8:d7:ba:32:f3:12:49:b7:76:55:01:52:43:c9:e7:
    ...
prime1:
    00:f3:e7:8f:7a:00:fc:bf:72:12:8f:c1:85:81:4b:
    75:a8:88:7c:5e:a6:3b:9e:d1:3c:02:53:e0:2e:f2:
    ...
prime2:
    00:dc:31:a0:2c:da:df:c5:1e:e3:20:ca:44:1b:9e:
    33:2a:69:8d:2d:7d:a4:d6:7d:eb:c1:75:cb:1f:d0:
    ...
exponent1:
    00:a1:e0:45:b1:4b:86:73:e9:59:b8:5f:50:24:07:
    d9:07:09:ce:c1:62:c2:9f:1d:6f:1e:7c:5c:85:cc:
    ...
exponent2:
    6e:70:f9:9c:e5:df:0c:b8:b4:45:13:0e:5c:27:da:
    13:f0:c3:1d:c9:02:2f:8f:12:fb:82:c0:71:e1:b9:
    ...
coefficient:
    5e:94:e2:3f:86:97:c4:24:8d:4b:e7:e9:ed:10:bc:
    e3:d5:79:3c:f8:bd:c5:33:5f:52:14:34:a0:72:83:
    ...

# 读取公钥信息
$ openssl rsa -pubin -in rsa_public_key.pem -text -noout
RSA Public-Key: (2048 bit)
Modulus:
    00:d1:ca:47:3a:c5:34:b1:2f:4e:f0:a7:29:0d:99:
    de:51:89:ae:1c:1f:81:22:53:7c:fe:c1:68:62:80:
    ...
Exponent: 65537 (0x10001)

应用公私钥加解密,如下:

# 加密
$ echo -n hello | openssl rsautl -encrypt -in - -inkey rsa_public_key.pem -pubin -out encrypt.bin 

# 解密
$ openssl rsautl -decrypt -in encrypt.bin -inkey rsa_private_key.pem 
hello

加密算法总结:

  1. 对称加密算法因为大多数操作都是相似 XOR 的位运算,加密速度很快,但像客户端 - 服务器这种模式,须要给每个客户端调配一个对称密钥,密钥治理难度较大。
  2. 非对称加密算法能够将公钥告知给所有客户端,服务端应用私钥解密,能很好的应答客户端 - 服务器模式,但因为须要做数学运算,加密速度较慢。

恋爱日记:晋升沟通效率

小李与小红理解到了对称与非对称加密算法的优缺点,决定联合应用两种密码学算法,如下:

  1. 小红开始时随机生成一个对称密钥,而后应用公钥算法加密,将加密后的对称密钥发送给小李。
  2. 小李应用私钥将对称密钥解密进去。
  3. 而后小红和小李就应用对称密钥加解密数据,以实现信息互通。
  4. 并且,小红和小李决定每隔一天,从新生成一个新的对称密钥。

混合明码零碎
嗯,他俩这方法还真不错,这种联合各种明码算法优缺点的办法,在密码学里叫 混合明码零碎 ,像 SSL/TLS 就是典型的混合明码零碎,看看 SSL/TLS 中的一个明码套件TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,它混合应用了多种明码算法,包含咱们前面会介绍的ECDHESHA256

密钥轮换
小李与小红每隔一天就更换一次对称密钥,这种定期更改密钥的形式叫密钥轮换,密钥轮换在秘密通信场景也常常应用,这样就算某个密钥被泄露,也不至于所有加密数据都失去爱护。

然而当大李理解到他们的这个计划后,笑了笑说:你们这个计划不满足 前向安全性 啊!

前向安全性

简而言之,前向安全性就是,当你的主密钥被泄露之后,在泄露工夫点之前通信的数据仍然是平安的,即便攻击者在网络中将你们之前的通信数据全都监听保留下来了。

像小李与小红其实创造了一种最简略的密钥协商计划,这种计划是小红应用 RSA 公钥将对称密钥加密后,间接通过网络发送给对方,但如果小李的 RSA 私钥不小心泄露了,那么他们之前每次协商的对称密钥都能被解密进去,从而通信数据也会被解密进去!

所以,这种通过加密协商密钥的计划,就不满足前向安全性。

密钥协商算法

因此,明码学家们创造了一类十分奇妙的密码学算法,不须要在网络中间接发送密钥,通信单方就能计算出同样的密钥进去,这类算法统称为密钥协商算法,如 DH 与 ECDH。

DH(Diffie-Hellman)算法原理如下:

假如 Ali 和 Bob 须要相互通信并共享密钥

  1. Ali 先给 Bob 一个明文共享参数 P,G,此信息能够被任何人辨认
  2. Ali 本人生成一个随机数 A(Ali 的私钥),并不将 A 通知包含 Bob 在内的任何人
  3. Bob 本人生成一个随机数 B(Bob 的私钥),并不将 B 通知包含 Ali 在内的任何人
  4. Ali 计算(G^A % P),并传送给 Bob
  5. Bob 计算(G^B % P),并传送给 Ali,通过计算 (G^A % P)^B % P = G^(A*B) % P = S 失去共享密钥
  6. Ali 同样通过计算 (G^B % P)^A % P = G^(A*B) % P = S 失去共享密钥

DH 算法安全性基于离散对数难题,当 P 是一个十分大的质数时,Ya=G^A % P 通过 Ya 很难推算出 A。

而 ECDH 是联合 ECC 与 DH 的密钥协商算法,其安全性基于椭圆曲线上的离散对数难题。

恋爱日记:完好的照片

原本小红与闺蜜小美是如影随行的,但当初小红很少和她玩了,并且小红每天在她背后夸耀男友,惹得小美醋心大发,心中不乐,决定棒打鸳鸯,于是她暗藏在网络里,将小红发给小李的密文胡乱批改后,再转发给小李,如下:

# 小美将图片中第 90000 个分组 (16 字节) 后的 160000 字节,篡改成随机字节
(head -c $((54+16*90000)) image4.bmp; head -c 160000 /dev/urandom; tail -c +$((54+16*90000+160000+1)) image4.bmp) > image5.bmp

而后,小李解密图片,发现自己收到的图片被解密后,女友照片中有些区域乌七八糟的,如下:

(head -c 54 image5.bmp;tail -c +55 image5.bmp | openssl enc -aes-128-cbc -d -in - -out - -k password -iv 0102030405060708) > image6.bmp

小李马上和大李沟通了此事,大李感觉,这应该是有人在网络中篡改了密文导致!

是的,AES 算法尽管能保障机密性,但无奈避免他人篡改密文,要想解决这个问题,有两种方法,如下:

  1. 应用认证加密算法能够防篡改,如 AES-GCM 算法,这类算法统称为 AEAD 算法,这里暂不做过多探讨。
  2. 应用单向散列算法,如 MD5、SHA1、SHA256 等,这是咱们接下来会介绍的 …

单向散列算法

单向散列算法,有时也称为 (密码学) 哈希算法,次要作用是生成数据的一个散列值,也称音讯摘要或“指纹”,用于验证数据在传输过程中是否产生了篡改,常见的散列算法有 MD5、SHA1、SHA256 等等。

尽管像 CRC32、CRC64 这样的哈希算法,也能生成 32 位或 64 位的数据摘要,但因为它们不是为密码学畛域而设计的,所以它们生成的数据散列值非常容易抵触碰撞,即不同数据生成的散列值雷同。

单向散列算法有如下特点:

  1. 强抗碰撞性,哪怕原数据只改一 bit,散列值也会产生很大的变动,要想找到两个散列值一样的对于人类有意义的数据,是十分艰难的。
  2. 单向性,通过数据能够计算出散列值,但通过散列值无奈反算出数据。

单向散列算法的用处:

  1. 因为原数据批改之后,散列值会产生扭转,所以 MD5 等密码学散列算法可用来检测数据是否被篡改。
  2. 因为像 MD5 等密码学散列算法,它们通常都具备十分强的抗碰撞性,对于人类产生的有意义的不同数据,简直不可能生成雷同的散列值,所以 MD5 等算法有时也会用来生成数据的惟一标识。

Linux 工具命令

在 Linux 中,可用如下命令应用单向散列算法:

# md5 生成 128 位的散列字节
$ echo -n hello | md5sum
5d41402abc4b2a76b9719d911017c592  -

# sha1 生成 160 位的散列字节
$ echo -n hello | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d  -

# sha256 生成 256 位的散列字节
$ echo -n hello | sha256sum
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  -

一般来说,生成的散列值长度越长,抗碰撞性越好,所以目前来说,个别举荐应用 SHA256 算法。

恋爱日记:我厌恶你!

理解了单向散列算法的作用后,小红与小李在前面的通信中应用了 SHA256,如果小李发现图片的散列值与小红给的不对应,就让小红重发一遍即可。

很快小美也发现了这个状况,心里更加不欢快了,通过她一番思考,想成小红能生成散列值,我也能够啊,于是小美给小李发送了一条“我厌恶你”的音讯,并且也发了这条音讯的 SHA256 散列值。

小李收到这条音讯后,大为震惊,不知是哪里惹小红不开心了,但与小红沟通后,发现小红基本就没有发这条音讯过去,有人假冒小红给小李发消息,还带有散列值,不知怎么办的小李,又找到了大李。

大李笑了笑,你们是时候应用音讯认证码技术了 …

音讯认证码

音讯认证码 (message authentication code) 是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为 MAC.

音讯认证码的输出包含任意长度的音讯和一个发送者与接收者之间共享的密钥,它能够输入固定长度的数据,这个数据称为 MAC 值。

明码学家们创造了很多音讯认证码算法,最常见有两类,一类是 HMAC,全称 Hash MAC,顾名思义就是基于密码学哈希算法实现的音讯认证码算法,另一类是 CMAC,全称 Ciper MAC,顾名思义就是基于加密算法实现的音讯认证码算法。

HMAC

而一般而言的 HMAC 算法,是指上面这样的规范 HMAC 算法。

HMAC 算法特点是,能够随便搭配单向散列算法,如 MD5、SHA1、SHA256 等,比方在 Java 中的 hmacWithSha256 算法,就是 HMAC 搭配 SHA256。

Linux 工具命令

在 Linux 中,hmac256 命令就是 hmacWithSha256,如下:

$ echo -n 'hello'|hmac256 'secret'
88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b

另外,咱们经常见到开放平台指定签名算法时,会应用如下的办法:
sign = md5(appid + text + appsecret)
其实这就是自行创造了一种简略的 HMAC 算法。

另外,如果应用这种拼接形式实现 MAC 算法,最好在 text 两侧都拼接上货色,具体可见:哈希长度扩大攻打:https://www.cnblogs.com/dre0m…

恋爱日记:我喜爱你!

小红与小李理解了音讯认证码技术后,立马决定应用 HMAC 算法,这也很快被小美发现了,小美发现如同无奈假冒小红发消息了,因为本人不晓得他们应用 HMAC 时的密钥,苦苦考虑中 …

有一次,小红被撩嗨了,头脑发热给小李发一句“我喜爱你”,但随后小红又悔恨了,感觉本人如此被动表白情意,前面恋爱过程会被小李拿捏的。

小李叫苦不迭,立马去找小红,后果小红否定这音讯是她发的,小李与小红争执起来,说密钥只有你知我知,不是你发的,难道是我发的?

小红成心调皮地说,谁晓得你是不是自恋狂啊!

小李伤心回到家后,与大李说了此事,大李刺激了一下小李,说是时候应用数字签名技术了 …

数字签名

从下面的问题,咱们能够发现,音讯认证码无奈防否定,起因是通信单方领有雷同的密钥,为了解决这个问题,须要发送方与接管方应用不同的密钥,发送方用一个密钥签名,接管方用另一个密钥验签,这就是数字签名技术。

而非对称加密技术就是应用不同密钥加解密的技术,刚好能够满足数字签名的需要,如下:

数字签名的生成与验签过程,和公钥加密的过程刚好是相同的,如下:

  1. 公钥加密的过程是,发送方应用公钥进行加密,而后接管方应用私钥进行解密。
  2. 公钥签名的过程是,签名方应用私钥生成签名,而后验签方应用公钥验签。

对于数字签名过程,须要留神两点:

  1. 所谓的签名其实就是私钥加密,而验签即是将签名值 (即密文) 应用公钥解密,而后与明文进行比照。
  2. 为了晋升签名、验签的速度,在签名 (加密) 前给明文数据做了散列,而解密后与明文散列值做比照。

注:实践上,用公钥签名,私钥验签也是能够的,但因为在定义上公钥是公开给他人的密钥,而如果多方都能够应用公钥签名的话,就不合乎签名的需要了。

Linux 工具命令

# 生成私钥与公钥
openssl genrsa -out rsa_private_key.pem 2048 
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout 

# 签名
echo -n hello | openssl rsautl -sign -in - -inkey rsa_private_key.pem -out sign 

# 验签 
openssl rsautl -verify -in sign -inkey rsa_public_key.pem -pubin 

为什么能够防否定?

因为私钥只有签名刚才有啊,除了它,其他人都无奈生成签名了,包含公钥持有方。

恋爱日记:离别吧!

在大李介绍了数字签名技术之后,小李与小红立马应用 RSAWithSha256 签名算法,当然这须要两人各生成一对密钥,如下:

  1. 小红本人生成一对公私钥后,将公钥发给小李,私钥则本人保留,谁都不通知。
  2. 小李本人也生成一对公私钥后,将公钥发给小红,私钥也本人保留,谁都不通知。
  3. 小红发消息时,同时应用本人私钥为音讯计算一个签名发给小李,小李则拿小红公钥验签。
  4. 小李发消息时,也应用本人私钥为音讯计算一个签名发给小红,小红则拿小李公钥验签。
    看起来完满了,小红与小李都无奈否定音讯了!

可好景不长,小美为了毁坏恋爱过程,发现了一种叫做中间人攻打的伎俩,如下:

中间人攻打

比方 Alice(小红)与 Bob(小李)通信,须要把 Bob 的公钥发送给 Alice,但 Alice 与 Bob 之间有个 Mallory(小美),Mallory 将 Bob 发送的公钥截获后,将本人的公钥发给了 Alice,而之后 Alice 理论在与 Mallory 通信,Mallory 与 Bob 在通信,Mallory 能够解密出所有通信内容!

于是,小美在小红与小李互发公钥时,将他们的公钥截获保存起来,而后将本人的公钥发给单方!于是,小美在两头能够随心所欲了,给单方发了一句“离别吧”,如下:

  1. 当小红用私钥给音讯签名时,小美截获了音讯,而后本人发一条音讯“离别吧”给小李,同时用本人的私钥签名音讯,并把签名也发给小李。
  2. 当小李收到音讯后,应用“小红的公钥”验签,而这个公钥理论是小美的公钥,于是验签通过,小李笃定音讯是小红发的。
  3. 小红也同理,收到“离别吧”音讯,且笃定音讯是小李发的。

好家伙,小李与小红伤心欲绝,差点真离别了!好在大李晓得这个音讯后,认真考查了小李与小红,感觉他们的确没有发这个音讯,猜想可能产生了中间人攻打!

大李在刺激了小红与小李后,说:我来给你俩做担保,将你们的公钥变成证书吧!

证书

信赖问题与 PKI

下面之所以呈现中间人攻打,是因为小红在收到小李的公钥时,并不知道这个公钥是不是小李的,反之亦然,那怎么证实这个公钥就是小李的呢?

  • 一是须要在公钥上写上小李的名字,但小李能够在公钥上写 ” 小李 ”,小美也能够在公钥上写 ” 小李 ”,所以仅仅有名字还不够
  • 二是须要在公钥上做数字签名,相似盖章一样,那谁来盖这个章?

回忆一下,咱们毕生中会办各种证书,学生证、身份证、结婚证,房产证,为什么你出示结婚证,他人就会置信你结婚了?因为结婚证是国家发的啊,下面有国家机构盖的章呢,咱们普通人有理由置信国家盖章的证书是实在的证书,毕竟它的章不好伪造,也没人敢伪造。

在计算机世界也一样,为了解决公钥认证问题,人们构建了公钥基础设施 PKI 和认证机构 CA,比方小李在本人的公钥写上名字,而后由大李 (CA 认证机构) 应用本人的私钥为其生成数字签名,而后将公钥、名字、数字签名打包成一个文件,这个文件就是小李的数字证书,就像由 CA 机构 (大李) 盖过章一样。

而小红在收到小李的数字证书后,她首先会应用大李 (CA 机构) 的公钥来验证数字签名是否正确,而后又会确认证书上的名字是不是小李,数字签名与名字都正确后,取出证书中的公钥与小李通信。

这外面大李就相似于 CA 机构,大李能够私底下将本人的公钥给小李与小红。

那对于互联网上千千万万的网民,怎么会有 CA 机构的公钥的?这是因为 CA 机构联结了操作系统、浏览器厂商,事后将它们的公钥默认内置到了操作系统或浏览器中。

证书例子:

如下,是百度网站的证书



证书上能够看到这样的证书门路,这是一个递归的过程,大的 CA 机构能够给中等的 CA 机构的证书盖章,中等的 CA 机构又能够小的 CA 机构的证书盖章,如此上来会造成一棵树,所以咱们的证书,个别都被根 CA 机构委托几次后的 CA 机构盖章的。

curl 与 openssl 也能够看到局部证书信息,如下:

curl -v https://www.baidu.com

openssl  s_client -connect www.baidu.com:443 -prexit

注:这里小红与小李单方都生成了证书,而在 CS 架构里,个别只须要服务端生成证书即可,因为客户端不须要提供证书,这也导致服务端收到的申请是不可信的,须要附加 Cookie 等认证机制并校验申请数据合法性。另外,SSL/TLS 其实是能够配置成双向认证的。

CA 机构职责

你可能还会有疑难,我本人生成一个公钥,而后在公钥上写上名字 baidu.com,而后给 CA 机构签名,那不一样能够施行中间人攻打?

的确有这样的可能性,但 CA 机构并不是轻易给证书签名的,它会让你出具各种证实资料并严格审查,只有认定你的确是 baidu 才会在证书上签名。

并且,只有 CA 机构的私钥不泄露,签名才牢靠,为了保障本人的私钥不被泄露,须要对私钥进行严格的访问控制,甚至派专人值守在私钥搁置处,因而,CA 机构签发证书是须要收钱的,就如同国家保障你的平安须要收税一样。

恋爱日记:欢畅时光

终于,应用了证书后,小红与小李迎来了他们的欢畅时光!然而,小美在理解到了 社会工程学攻打 后,居然也偷偷的与大李约会了 …

明码算法倡议

  1. 加密算法,倡议应用 AES,加密模式应用 CBC 或 GCM,一般安全级别 AES128 足够了,但思考到量子计算机的威逼,绝密场景倡议应用 AES256。
  2. RSA 算法,要保障安全性,至多须要应用 2048 位的密钥长度。
  3. 密钥协商算法,为保障前向安全性,倡议应用 ECDH 密钥协商算法,且密钥长度至多 384 位。
  4. 哈希认证算法,目前不倡议应用 MD5、SHA1,HMAC 算法目前还是十分平安的。

往期内容

原来 awk 真是神器啊
Linux 文本命令技巧 (上)
Linux 文本命令技巧(下)
字符编码解惑

正文完
 0