Https原理
密码学基础
在正式讲解HTTPS协议之前,我们首先要知道一些密码学的知识。
明文: 明文指的是未被加密过的原始数据。
密文:明文被某种加密算法加密之后,会变成密文。
密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥。
对称加密:对称加密又叫做私钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。对称加密的特点是算法公开、加密和解密速度快,适合于对大数据量进行加密,常见的对称加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。
其加密过程如下:明文 + 加密算法 + 私钥 => 密文
解密过程如下:密文 + 解密算法 + 私钥 => 明文
对称加密中用到的密钥叫做私钥,私钥表示个人私有的密钥,即该密钥不能被泄露。
其加密过程中的私钥与解密过程中用到的私钥是同一个密钥,这也是称加密之所以称之为“对称”的原因。由于对称加密的算法是公开的,所以一旦私钥被泄露,那么密文就很容易被破解,所以对称加密的缺点是密钥安全管理困难。
非对称加密:非对称加密也叫做公钥加密。非对称加密与对称加密相比,其安全性更好。对称加密的通信双方使用相同的密钥,如果一方的密钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公共的密钥,任何人都可以获得该密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。
被公钥加密过的密文只能被私钥解密,过程如下:
明文 + 加密算法 + 公钥 => 密文, 密文 + 解密算法 + 私钥 => 明文
被私钥加密过的密文只能被公钥解密,过程如下:
明文 + 加密算法 + 私钥 => 密文, 密文 + 解密算法 + 公钥 => 明文
由于加密和解密使用了两个不同的密钥,这就是非对称加密“非对称”的原因。
非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
在非对称加密中使用的主要算法有:RSA、Elgamal、Rabin、D-H、ECC(椭圆曲线加密算法)等。
- HTTPS协议 = HTTP协议 + SSL/TLS协议
- Https是采用对称加密和非对称加密结合的加密方式的。在最开始的建立SSL连接的时候采用非对称加密这种耗时长的加密方式,在建立完SSL连接后采用对称加密这种耗时短的加密方式。
- SSL协议是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL协议使用。
主要流程
首先是建立SSL连接部分:
- 客户端通过发送 Client Hello 报文开始 SSL通信。报文中包含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
- 服务器可进行 SSL通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 之后服务器发送 Certificate 报文。报文中包含公开密钥证书。(这里的证书是怎么来的,如何验证的我们一会再说,我们只要知道它包含服务器的公钥就够了)
- 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL握手协商部分结束。
- SSL第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该随机密码串已用步骤 3 中的公开密钥进行加密。
- 接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
- 客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器用自己的私钥解开步骤5中的报文,得到随机密码串。服务器同样发送 Change Cipher Spec 报文。
- 服务器同样发送 Finished 报文。
服务器和客户端的 Finished 报文交换完毕之后,SSL连接就算建立完成。
- 之后的第10第11步的请求和响应都使用对称加密,使用随机密码串作为密码参数来传递信息。
-
最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP的通信
数字证书
数字证书是怎么来的:
当服务器接收到客户端发来的请求时,会向客户端发送服务器自己的公钥,但是黑客有可能中途篡改公钥,将其改成黑客自己的,所以有个问题,客户端怎么信赖这个公钥是自己想要访问的服务器的公钥而不是黑客的呢? 这时候就需要用到数字证书。数字证书由数字证书认证机构(CA,Certificate Authority)和其相关机关颁发,认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。
那CA怎么对公钥做担保认证呢?
CA本身也有一对公钥和私钥,CA会用CA自己的私钥对要进行认证的公钥进行非对称加密,此处待认证的公钥就相当于是明文,加密完之后,得到的密文再加上证书的过期时间、颁发给、颁发者等信息,就组成了数字证书。
那么就又回到刚刚步骤3中的问题了,
客户端如何验证证书的真伪呢?
×××××××××××××××证书内容开始×××××××××××××××××
Issuer : 某某CA
Subject : 某某公司
Valid from : 某个日期
Valid to: 某个日期
Public Key : 一串很长的数字
…… 其它的一些证书内容……
证书的指纹
计算指纹所使用的指纹算法
×××××××××××××××证书内容结束×××××××××××××××××
客户端的浏览器一般在安装出厂时都会带有一些值得信赖的大CA的公钥和指纹,浏览器在收到证书后,就会扫描看看这个证书里的CA是否被信任,如果信任,则使用它的公钥对它的指纹采用它的指纹算法去计算,得到的结果如果和存在浏览器中的指纹一致,则可以信任。
CA的公钥有没有可能是假的呢?
嵌入在浏览器中CA的公钥和指纹确实有可能被篡改
哎呀,那可咋办?
那你平时不要去逛一些奇怪的网站啊,就算逛了,如果弹出是否信任该证书/CA的时候也不要同意啊 ( `д´)
参考资料:
《图解HTTP》