密码学基础

2017-4-13

是时候认认真真搞明白网络中用到的密码学的一些东西了。

基础

单钥密码体制/对称密码体制

指加密密钥和解密密钥为同一密钥的密码体制,只有一个密钥,信息由该密钥加密后,只能由该密钥解密,因此通信双方必须共同持有该密钥。

常用的有DES、AES加密。

双钥密码体制/非对称密码体制/公开密钥密码体制

分为公钥和密钥,如果信息由公钥加密了,就只能由密钥解开,反过来,如果信息由密钥加密了,也只能由公钥解开。

公钥是公开的,谁都可以持有,密钥是私有的,自己保管不给别人知道。

知道公钥的人,将信息用公钥加密,发给持有密钥的人,信息只有持有私钥的人能解开,这就实现了信息的加密传输

持有密钥的人,将信息用密钥加密,公布到网络上,只有对应的公钥能解开,这就保证了该信息一定是持有密钥的人发出来的,这就实现了信息的认证

常用的有RSA、DSA,其中RSA用的最多。

摘要算法

又叫作Hash算法或散列算法,摘要算法生成信息的摘要,将信息“浓缩”。信息的摘要相当于这个信息的ID,如果信息的内容发生改变,摘要就会变化,所以要确保信息没有被改变,只要看信息的摘要有没有变就可以了。

如一个文件的摘要是85091b7f1334c24a。只要这个文件发生了一点点改变,其摘要就会发生变化。

论坛分享文件时,也经常有人贴出文件的摘要,防止自己分享的文件在下载过程中或者下载完成后被别人修改,网友下载完文件后对文件进行摘要算法计算出摘要,对比一下分享的人贴出的摘要,就可以知道文件是不是被修改过。

常用的有MD5、SHA-1、SHA-2、SHA-256

随着科技的发展,MD5已经一定程度上被破解,也就是可以制造出两个不同的文件,他们MD5值是一样的

SHA-1、SHA-2也被大家认为不那么安全,其中SHA-1也已经被谷歌制破解出了SHA-1的首例碰撞

现在大家认为比较安全的是SHA-256

数字信封和数字签名

数字信封

前面提到用公钥将信息加密,发送给私钥持有人,就实现了信息的加密传输。

双钥密码体制的算法计算量比较大,如果信息的内容很长,比如几个G,那如果还用这种方式来做就会效率很低。

所以结合对称密钥体制,首先生成一个单钥密码体制的密码,然后用这个密码对信息进行加密,然后对这个密码用公钥再加密一次,这个被公钥加密后的对称密钥被称之为数字信封,将加密后的信息与数字信封一起发送给密钥的持有人。

密钥持有人对数字信封用密钥解密,得到一个密码,再用这个密码对加密后的信息解密。

这种传输,很像在现实生活中,我们将信件用信封装起来,发送给接收者,保证信件在传输的过程中不被别人读到。

这样就实现了大数据加密传输

数字签名

前面提到持有密钥的人用密钥加密信息,只有他对应的公钥可以解开,这样就实现了信息的认证,确保了该信息是持有密钥的那个人发出来的。

双钥密码体制的算法计算量比较大,如果信息的内容很长,比如几个G,那如果还用这种方式来做就会效率很低。

所以结合摘要算法,对原始信息的摘要用密匙加密,然后将加密后的摘要与原始信息一起发送给接收方,接收方用公钥将加密后的摘要解密,然后再讲收到的信息进行摘要计算,将解密得到的摘要和自己计算的摘要进行比对,如果相等,就确保了该信息是公钥持有人发出来的,并且没有被修改过。

这种将原信息跟加密后的摘要一起发送给接收方的方式,很像用电脑打印一封信,然后在最后手写签上自己的姓名,让对方确定这封信是由自己发出的。所以这个加密后的摘要就叫做数字签名

这样就实现了大数据信息的认证

应用

假设有A、B两人,他们都有自己的密钥,并持有对方的公钥。这很容易做到。

A的密钥记为PA ,A的密钥记为SA,即Public A、Secret A缩写

B的密钥记为PB,B的密钥记为SB

信息原文记为x

PA加密过的信息记为 PA(x),其他同理

回顾一下:

简化版

简化版不考虑数字信封和数字签名

发送者A:

  1. A准备要传送的数字信息x
  2. A对数字信息x用自己的密钥加密,得到SA加密过的数字信息SA( x )
  3. A对SA( x )再用B的公钥加密,得到PB( SA( x ) )
  4. A将PB( SA( x ) )发送给B

接受者B:

  1. B对PB( SA( x ) )用SB解密,得到SA( x ),由于SB是只有B才有的,这一步除了B谁也做不到,保证了信息的私密性。
  2. B对SA( x )用PA解密,得到x,这里只要能解密成功,就能确保x是A发过来的

复杂版

我们把数字信封和数字签名加进去

假设随机生成的对称密码为D,用D对x加密记为D(x)

x的摘要记为H(x)

发送者A:

  1. A准备要传送的数字信息x
  2. A对x进行摘要计算,得到H( x )
  3. A用自己的密钥对H( x )加密,得到SA( H( x ) )
  4. A生成一个对称密码D,并对x + SA( H( x ) )进行加密,得到D( x + SA( H( x ) ) )
  5. A用PB对D进行加密,得到PB( D )
  6. A将PB( D )和D( x + SA( H( x ) ) )一起发送给B

接受者B:

  1. B对PB(D)用自己的密钥解密,得到D,这一步除了B谁也做不到,保证了信息的私密性。
  2. B对D( x+SA( H(x) ) )用D解密,得到 x + SA( H( x ) ),即分别得到了x和 SA( H( x ) )
  3. B对SA( H( x ) )用PA解密,得到H( x ),如果能解密,就能确保信息是A发过来的
  4. B对x再进行一次H计算,与上一步的到的H( x )比对,如果一样,就能确保A发过来的信息没有被修改过

数字证书

复杂的情况来了,这时候出现了一个坏蛋C,他生成了一对密钥,PC、SC,然后把A绑起来,把自己伪造成A,跟B通信。

由于一开始大家交换公钥的时候,无法确定对方的身份,所以C很容易就可以欺骗B了。

为了解决这个问题,证书中心(certificate authority,简称CA)出现了。证书中心也有自己的密钥和公钥,这里记为SCA、PCA

A先在CA注册一下,做公钥认证。CA用自己的密钥对A的公钥和一些相关信息一起加密,生成数字证书(Digital Certificate),我们可以记为SCA( PA )。

接下来A对B发信息的时候,都附上SCA( PA )。

B收到消息后,先用PCA对SCA( PA )解密,得到PA,再进行接下来的操作。

因为CA的公钥是一开始就安装在系统和浏览器里的,C没法替换,C就无法伪装成A了。

证书链

上面的做法,已经解决了安全的问题,但是CA怎么确认呢。

如果全世界只有一个CA,那全世界这么多网站,肯定忙不过来。

如果各个国家、各个省份和公司各自搞各自的CA,操作系统和浏览器不可能把世界上所有的CA公钥都预先存好。

CA分为两种,root CAsintermediate CAs,root CAs的数量屈指可数,大家都公认的就那么几家,大家都会把root CAs的公钥预先存好在自己的浏览器和系统里。

一般各个网站得到的证书是由intermediate CAs颁发的。

root CAsintermediate CAs我们分别缩写为rCA和iCA,假设有一个网站Z。

接下来我们看一下数据传输流程简化版(忽略发送方将数据用接受对方的公钥加密这一步骤)的流程:

  1. iCA将Z的公钥用自己的私钥加密,也就是给Z颁发证书。
  2. Z把网站的数据加密后,附上【iCA给Z颁发的证书】(里面有加密过的自己的公钥),一同发给浏览器。
  3. 浏览器收到后用【iCA的公钥】解开【iCA给Z颁发的证书】,得到【Z的公钥】,进而解开网站的加密的信息。

上面怎么保证iCA的公钥可信度呢,这就需要rCA给iCA颁发证书,也就是rCA用自己的私钥将iCA的公钥加密。

然后流程里的第二步就变成了:

Z把网站的数据加密后,附上【iCA颁发给Z颁发的证书】(里面有加密过的自己的公钥),还附上【rCA给iCA颁发的证书】,一同发给浏览器。

浏览器的操作就变成:

  1. 用【rCA的公钥】解开【rCA给iCA颁发的证书】,得到【iCA的公钥】
  2. 再用【iCA的公钥】解开【iCA颁发给Z颁发的证书】,得到【Z的公钥】
  3. 用【Z的公钥】解开网站信息

证书链就是上面这样,为了验证Z的公钥,我们找来了iCA颁发证书,又为了雅正iCA的公钥,我们找来了rCA颁发证书。

iCA可能有好几个,一个一个往下信任。

这样,大家电脑里只要存储rCA的公钥,就足够建立一整套信任了。

根证书

根证书,根证书是CA自己给自己颁发的证书,简单来说就是用自己的密匙加密自己的公钥,或者不加密。

root CAs的公钥,都是以根证书的方式,预先存好在浏览器和操作系统中

总结

数字证书、数字签名可以用生活中的例子啊来打比方,方便理解。

比如我需要证明一段数据是我创造的,我对这份数据进行签名,然后数字证书可以证明这个签名是我签的。

就好像现实生活照我要证明一份和同时我签的:

就可以证明真的是我签下了这份合同。



参考:

什么是数字签名?什么是数字信封?他们如何使用

双钥密码

数字签名是什么?

数字证书及CA的扫盲介绍

SSL question: How does a ROOT CA verify a signature

证书链-Digital Certificates