对称加密
- 加密前的原始数据,叫做 原文( original text ),或者 明文( plain text );
- 加密后的不规则( scrambled )数据,通常叫做 密文( cipher text );
- 加密所用的密码,通常叫做 密钥( secret key );
对称加密(symmetric encryption)算法最大的特点是,它只有一把密钥,加密和解密过程用的都是同一把密钥,这也符合大众对加密算法的认知,用密码对数据进行加密之后,必须用同一个密码才能将数据解密出来
- AES ,高级加密标准,新一代加密算法标准,速度快,安全级别高;
- DES ,数据加密标准,速度较快,适用于加密大量数据,但安全性较弱;
- Blowfish ,使用变长密钥,运行速度很快,非专利算法,没有使用限制;
- etc
非对称加密
从前有一个黑帮,老大和手下们之间的通信必须加密确保安全。于此同时,老大希望手下发给他的信息,不能被其他手下知晓。若采用对称加密算法,只能给每个手下都分配一个独立的密钥,但老大觉得太麻烦了。该怎么办呢?
黑帮老大希望他只维护一份密钥,就能达到这样的效果,有办法做到吗?
可以用非对称加密(asymmetric encryption)
非对称加密,顾明思议,在加密和解密环节用的密钥是不同的。
非对称加密算法需要两把不同的密钥,这两把密钥组成一对:
- 公钥( public key ),公钥用来对数据进行 加密 ;
- 私钥( private key ),也称为 密钥( secret key ),用来对数据进行 解密 ;
- 公钥和私钥总是成对出现,用公钥加密后得到的密文,必须用对应的私钥才能解密;
这套加密机制完美解决了黑帮老大的难题,他只需要生成一对密钥:公钥分发给手下们,他们先用公钥加密信息,再发老大;老大接到密文,就用自己保管的私钥来解密;手下们就算拿到别人发的密文也解不开,因为私钥只有他们老大才有。
数学原理
公钥和私钥的加密机制看起来非常不可思议,这一切其实来一个神奇的数学原理。
我们来做一个数字游戏,您随便写下一个整数 m (1<m<7387 ),然后计算m ^3 mod 7387 并把结果告诉我,我就知道您写下的整数 m 是什么
|
|
公钥参数 3 和 7387 ,私钥参数 4811 和 7387 又是怎么生成的呢?
第一步,随机选择两个质数 p 和 q :
p = 83 q = 89
第二步,计算 p 和 q 的乘积 n :
n = p * q = 7387
第三步,计算 n 的欧拉函数 ,记为 phi :
φ(n) = (p-1) * (q-1) = 7216
第四步,随机选择一个整数 e ,满足1<e<φ(n),且 e 和φ(n)互质:
选一个质数 e ,使得不能被 e 整除即可。
第五步,计算 e 对φ(n)的模反元素 d ,即找到一个数 d 使得 ed 除以φ(n)的余数为 1 :
ed ≡ 1 mod(φ ( n )) <=> ed = kφ(n) + 1
可以找到一个d :4811
安全性分析
那么,有无可能在已知n和e的情况下,推导出d?
|
|
大整数的因数分解,是一件非常困难的事情
目前,能够被破解的 n 最大位数是 768 位(这里提到的位是指二进制位),因此有人开始质疑 1024 位密钥的安全性。现在推荐的密钥长度至少要 2048 位,只要长度足够,安全性完全不用担心
应用场景
加密
公钥加密私钥解密是非对称加密算法最典型的应用场景,特别适用于密钥需要公开的场景,比如 传输层安全协议 TLS ,它为通讯双方提供可靠的加密连接
如果没有非对称加密算法,TLS 将无法实现。因为对称加密算法要求双方使用同一密钥,加密连接建立之前,只能明文协商密钥。试想浏览器想跟服务器建立安全连接,无论是它选定密钥然后发给服务器,还是服务器选定密钥发给它,只要密钥经过明文传输,加密就失去意义。
有了非对称加密算法,服务器可以生成一对密钥,私钥自己保管,公钥可以公开。当浏览器请求建立加密连接时,服务器可以将公钥发给浏览器,因为公钥是可以公开的。浏览器将敏感信息用公钥加密后再发给浏览器,只有掌握私钥的服务器才能解密,他人便无法知晓。
同理,服务器想发敏感信息给客户端,必须由客户端生成的公钥加密。换句话讲,每对密钥解决一个方向的加密问题,通讯双方都需要生成自己的密钥对,负责加密对方发来的数据。
由于非对称加密算法运算复杂,加密效率不高,通常只是用来加密少量的关键信息,比如协商密钥。回到 TLS 这个例子,其实可以借助非对称加密算法协商密钥,从而直接使用更高效的对称加密算法来加密数据:
- 服务器生成公钥和私钥 对;
- 客户端(浏览器)连接上来后,服务器将公钥发给客户端;
- 客户端随机生成一个用于对称加密( AES )的密钥;
- 客户端用公钥对生成的密钥进行加密,然后后发给服务器;
- 服务器收到客户端用公钥加密的密钥后,用自己的私钥解密,至此密钥协商完毕;
- 由于私钥只有服务器才有,因此第三方无法知晓客户端选定的密钥是啥;
- 此后通信双方采用对称加密,以该密钥加密数据;
签名
实际上,私钥也可以用来加密数据,加密后的密文只有公钥才能解密。尽管如此,由于公钥是公开的,因此这个机制不能来加密数据,但可以对用来对数据进行签名防伪。
数字证书(certificate)
- 信息摘要( digest ),数据经过哈希算法得到的一串哈希值,代表数据的特征,也称为数据指纹;
- 摘要算法 ,可以把任意长度的数据,映射成一个定长的字符串(哈希值);
- 由于哈希冲突的存在,两份不同的数据,有可能算出相同的摘要值;
- 摘要算法无法用于数据加密,通常用来校验数据完整性,即 数据防伪 ;
- 常见的摘要算法有:MD5 、SHA1 、SHA256 、SHA512 。
- 数字签名( signature ),摘要由私钥加密后,得到的摘要密文就是数字签名;
- 签名,由数据发送方生成,这是一个 加密 过程(使用私钥);
- 验签,由数据接收方校验,这是一个 解密 过程(使用公钥);
- 数字签名只能由私钥生成,因此第三方无法伪造;
在介绍密钥协商时,我们提到服务器先将公钥发给客户端,用公钥保护对称加密密钥,确保通信内容不会被第三方获悉。但如果客户端连接的服务器是假的呢?如果用户对假网站信以为真,输入了账号密码,那么这些敏感信息都会被假网站窃取!
上节我们也讨论了数字签名,通过它可以实现数据防伪。那么,我们是不是可以利用这项技术来甄别仿冒站点呢
- 权威机构生成一对密钥,并提供站点认证审核和数字签名颁发服务;
- 站点管理员将站点信息,包括域名、运营单位、公钥等信息发给权威机构审核;
- 权威机构对提交上来的站点信息进行审核,审核通过则用私钥签名后返回给站点管理员;
- 客户端(浏览器)连接站点服务器,服务器将站点信息以及对应的数字签名发给客户端;
- 客户端用权威机构提供的公钥来校验数字签名,即可判断站点信息的真伪性;
- 签名验证通过,客户端从站点信息中取出公钥,与服务端协商密钥,发起加密通信;
- 由于签名用的私钥只有权威机构掌握,黑客无法伪造数字签名,也就无法架设仿冒站点;
- 权威机构必须由可信的单位运营;
你可能会觉得,黑客直接盗用站点信息和签名不就可以伪造原站点了嘛?此言差矣!因为公钥属于站点信息
的一 部分,也会参与签名!客户端和服务端协商密钥时,会使用这个公钥加密密钥。由于黑客不掌握站点私 钥,因此 加密连接无法建立!黑客把公钥替换成自己的吧,签名就不对,肯定会被验出来!
证书签发实验
CA权威机构
首先,权威机构需要生成一对密钥,cakey.pem 是私钥,
|
|
然后,生成根证书签发申请文件( csr 文件):
|
|
证书申请文件包含权威机构的信息,包括机构信息(Subject )和公钥(Public Key 部分)可以用下面命令查看:
|
|
最后,自签根证书( cer 文件 ):
|
|
这一步生成的 cer 文件就是根证书文件,它的主要作用是承载权威机构公钥,以便预装在操作系统或者其他终端。它同样会包含权威机构的信息,公钥,以及对应的签名。
商业站点(服务端)
首先,站点管理员生成一对密钥
|
|
然后,生成证书签发申请文件( csr 文件):
|
|
证书申请文件包含站点信息和公钥,站点管理员将证书申请文件发给权威机构审核,
权威机构对申请进行审核,审核通过则用自己的私钥对它进行签名,生成证书(cer 文件):
|
|
证书中保存着包括公钥在内的站点信息,以及权威机构对这些信息的签名。管理员接到权威机构颁发的证书,就可以部署网站了
浏览器(客户端)
客户端浏览器访问站点,服务端会将其证书发给客户端。客户端先对证书签名进行验证,步骤如下:
- 重新对证书中的站点信息计算 摘要值 ;
- 用公钥对证书中的签名进行解密,得到证书的原始摘要值;
- 公钥通常由根证书提供,根证书通常预装在系统里;
- 对比两个摘要值看是否一致;
调用 openssl 工具,一行命令即可完成签名验证
|
|
总结
数字证书是支撑互联网身份认证的重要技术手段,可以简单理解成经过 CA 权威结构签名认证过的站点信息。由于经过 CA 签名,第三方无法通过伪造手段冒充身份。
- 证书由站点信息和 CA 签名组成,站点信息包含站点公钥,公钥用于协商对称加密密钥;
- 证书由 CA 权威机构审核签发,签名用的是 CA 的私钥;
- CA 公钥通常以根证书形式预装在系统内,客户端通过它来验证证书签名;
- 有了数字签名,黑客无法对证书进行篡改,也无法伪造证书,因此无法部署仿冒站点;
- 若只窃取原站点证书,不做篡改,客户端使用真实站点的公钥,而黑客无法掌握站点私钥,因此加密连接无法建立;
- 如果篡改原站点证书,换上自己的公钥,但因为没有 CA 私钥无法生成合法签名,也会被识别出来;