Https原理解析
序言
我们已知http是基于明文传输,所以在网络中传输一些隐私数据没有办法保证一些安全性.所以我们可以通过一些加密方式来完成,加密方式有对称加密和非对称加密,下面会详细介绍一下两者加密方式特性.本文不对tcp握手流程作过多讲解. (有问题欢迎留言探讨)
对称加密
对称加密:加密和解密用的是同一个秘钥
常用对称加密算法有DES、3DES、AES
3DES就是三次DES加密
AES加密算法就是众多对称加密算法中的一种,它的英文全称是Advanced Encryption
Standard,翻译过来是高级加密标准,它是用来替代之前的DES加密算法的。
AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数
据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组
为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不
同,推荐加密轮数也不同。如AES-128,也就是密钥的长度为128位,加密轮数为10轮。
关于AES加密,
详细可参考博客:点击直达
非对称加密
非对称加密有两个秘钥,分为公钥和私钥,公钥和私钥可以相互解密对方加密的密文.常见的
对称加密算法有:RSA、ECC(移动设备用)、Diffie-Hellman(密钥协商)、
ElGamal、DSA(数字签名用)。
Diffie-Hellman算法
DH算法的主要功能是用于在不安全的通道中交换对称加密的密钥,而不适用于加密数据进行
传输(效率慢)
DH算法原理:
1.通信双方A和B约定两个大整数 n 和 g (^为次方,mod为取余)(n和g不是随便的,
需要满足DH算法,不然很容易就暴力破解)
2.A生成一个随机数a(密钥),a保密,并且把g的a次方对n取余(结果Ka)发送个B
(Ka = g^a mod n)
3.B生成一个随机数b,b保密,并且吧G的b次方对n取余(结果Kb)发送给A
(kb = g^b mod n)
4.A现在拥有Kb和a,B现在拥有Ka和b
5.A计算K = Kb ^ a mod n
6.b计算k = Ka ^ b mon n
7.Kb ^ a mod n = (g^b mod n) ^ a mon n
= (g ^ a mod n) ^b mod n
(emm,离散不好表示没想明白,数学家证明了上面是成立的)
8.所以k就是密钥.
拦截者只能获取到Ka和Kb,n和g,对于大数n和g,利用离散对数来计算k是非常困难的事.
大致流程如下:
1. server 构建密钥对:公钥public key1 和私钥 private key1
2. server --> client:server向client公开自己的公钥public key1
3. client (根据public key1,就是上面所述的n和g) 构建自己的本地密钥对:
public key2 和private key2
4. client --> server:client 向server 公开自己的公钥public key2
5. server 使用密钥对:private key1,public key2计算出密钥Y1
6. client 使用密钥对:private key2,public key1计算出密钥Y2
7. 根据上面描述的算法,密钥Y1 = Y2
SSL和TLS
分析https的流程必要性
- 只用对称加密来实现
- 分步骤分析,如果我们选择对称加密来加密数据,client和server都是用相同密钥来加密和解密,实现数据的安全性.但是中间存在两个问题
- 密钥如何保证传输安全的问题
- 服务端需要维护大量的密钥对
- 只用非对称加密来实现
- 非对称加密和对称加密都有相同的问题,就是这个密钥如何传输的问题.
- 需要维护大量的密钥对
所以我们单独使用其中一种是没有办法很好的实现的,所以https就是将两者结合起来,取其精华
https握手流程
先大致讲一下整体流程,下面会分析如何保证安全,为何需要这样操作保证安全.
- 客户端 -> 服务端 Handshake Type : Client Hello 同时会带一个随机的串random1(这个后面会用到),客户端支持的加密算法列表和客户端支持的TLS版本给server
- 服务端 -> 客户端 一次会顺序返回3个包,这个好像也是HTTPS的一种优化
- Handshake Type : Server Hello 第一个包内容包含一个随机的串random2(这个后面也会用到)
- Handshake Type : Certufucate 第二个包会把证书信息返回给客户端,证书里面包含有效期,公钥信息,服务器选择的对称加密算法
-
Handshake Type : Server Key Exchange 第三个包会将dh算法参数和生成的公钥返回给client,并且发送Server Hello Done表示结束
-
客户端 -> 服务端 客户端使用相同的DH算法参数生成客户端的公钥和私钥,将公钥发送给服务端.(客户端和服务端可以通过DH算法,算出对称加密密钥)
-
(优化)客户端会发送一个ticket给服务端,用于短时间内如果重新连接时,https快速验证复用.
到此为止,SSL or TLS 握手就已经完成,client和server都有了对称加密密钥,这时候就会使用第二步约定好的对称加密算法进行数据的传输.
在第三步的过程中,使用的是DH算法,还有一种方式是使用RSA算法,使用公钥加密random3发送给server,server使用私钥进行解密,这样获得的random1+random2+random3就是对称加密的密钥.
整个SSL or TLS 握手流程都是明文传输的,也没有办法进行加密,拦截者可以获取到公钥,random1和random2串,但是dh交换(或者RSA算法)得到的random3是没有办法被拦截者获取的.因此来保证数据传输的安全性.
分析如果被拦截,是否有风险
-
如果client -> server : client Hello 被拦截,拦截者成为中间者,发送自己的证书,公钥,签名给client,如何处理?
答:如果拦截者发送自己的证书,那么client 在解析证书时,对比CA机构信息和域名信息,浏览器根本不会信任这个证书,也就不会信任这个链接,在chrome上访问指定域名(但是返回证书不是这个域名),会直接拒绝链接.即使拦截者自己签发了证书,域名信息对了,但是CA机构大多数内置在浏览器之内,还是不信任链接.
-
中间是否会被拦截者拦截到隐私数据,或者会被拦截者拿到对称加密密钥解析出数据?
答:我们经过上面的分析发现,拦截者只能拿到random1串和random2串,和非对称加密的公钥,并没有办法拿到RSA算法加密的random3串,也就没有办法拿到对称加密密钥.
-
拦截者是否能够成为DH算法中的中间者?如果成为中间者,是否可以和client交换获取密钥?
答:这个问题其实就是DH算法能否被破解的问题,答案,很难,当两个共有数都为大数时,基本不可能被破解.首先,拦截者可以获取共有数A和B,client的共有PBc和server的共有数PBs,但是还是很难计算出密钥,所以暂时来看基本很难破解.
HTTPS优化
-
会话复用(session ID和session ticket)
会话复用原理也比较简单,就是连接过之后,客户端和服务端都保存下大家协商好的密钥,在后续请求中直接使用.
-
session ID
client或server会保存session ID,后续需要重新请求的时候,会带上session ID,如果server能找到匹配的session ID,则快速握手完成.
-
session ticket
nginx已经默认优先使用了session ticket,session ticket是用服务端密钥加密过的会话信息,保存在浏览器本地,如果需要 重新请求握手,会在client hello中带上session ticket,如果server可以解析成功,则快速握手完成. (nginx中使用 ssl_session_ticket_key file; 指令来配置用于加密或解密SSL session_ticket的密钥, 如果用了多个指令文件,则仅第一个指令文件中的密钥用来加密; 其它的密钥文件,并且第一个密钥文件都可以用做解密.)
session ID其实是有一些弊端,首先,当负载均衡时,如果多机没有同步session ID信息,那我们并不能保证session ID能被上次保存的server接收.
-
-
CDN接入
利用CDN可以大大减少传输时延
-
硬件加速
可以接入一些专门用于解密计算的SSL硬件加速卡,解放CPU,加快解密速度