初识https协议加密过程
为什么不用http而要使用https
当我们在使用http协议时候,由于http协议在网络中是明文传输的,明文数据会经过路由器、wifi 热点、通信服务运营商、代理服务器等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击,所以我们才需要对信息进行加密。,例如,我在控制台使用命令curl www.baidu.com
访问百度
并使用命令ping www.baidu.com
获取百度的ip地址
然后打开抓包工具,获取http请求
就可以看到一个完整的http请求,足以可见,http请求在网络中是明文传输的。而https是在应用层和传输层tcp之间新增了一层软件层(比如SSL或者TLS),这个软件层本身也是属于应用层,这个软件层主要负责对数据进行加密或者解密。本文主要就是介绍https是如何做到加密的
常见的加密方式
对称加密
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密,特征:加密和解密所用的密钥是相同的
• 常见对称加密算法(了解):DES、3DES、AES、TDEA、Blowfish、RC2 等
• 特点:算法公开、计算量小、加密速度快、加密效率⾼
对称加密其实就是通过同一个 “密钥” , 把明文加密成密文, 并且也能把密文解密成明文.
非对称加密
需要两个密钥来进行加密和解密,这两个密钥分别是是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
• 常见非对称加密算法(了解):RSA,DSA,ECDSA
• 特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。
非对称加密要用到两个密钥, 一个叫做 “公钥”, 一个叫做 “私钥”. 公钥和私钥是配对的.
使用方式有两类:
• 通过公钥对明文加密, 变成密文
• 通过私钥对密文解密, 变成明文
(即如果用公钥加密的话,只有私钥能解密)
也可以反着用
• 通过私钥对明文加密, 变成密文
• 通过公钥对密文解密, 变成明文
数据摘要&&数据指纹
数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash 函数)对信息进行运算, 生成一串固定⻓度的数字摘要。数字指纹并不是一种加密机制,但可以用来判断数据有没有被篡改。
摘要常见算法:有 MD5、SHA1、SHA256、SHA512 等,算法把无限的映射成
有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)
摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不
过从摘要很难反推原信息,通常用来进行数据对比
https的工作过程探究
方案一:只使用对称加密
即通信双方各自持有同一个密钥,且都使用该密钥进行加密和解密(如果该密钥是不被第三者获得的,那么双方的通信安全自然是有保证的)。
但是由于服务器同一时刻其实是给很多客户端提供服务的, 这么多客户端, 每个人用的秘钥都必须是不同的(如果是相同那密钥就会导致非常容易扩散)。因此服务器就需要维护每个客户端和每个密钥之间的关联关系, 这也是个很麻烦的事情
比较理想的方式就是在客户端和服务器端在建立联系之初就商量好使用的密钥是什么,中间就会不可避免地涉及到对于密钥地交换。但是如果对密钥进行明文传输,则非常容易被"中间人"获取密钥,这样即使客户端和服务端进行通信是使用密文通信的,中间的请求信息也会被破解。
所以,密钥的交换也需要加密传输。但是,想要对密钥进行加密传输,就需要事先约定一个"密钥的密钥",这就变成一个先有鸡还是现有蛋的问题了,所以,对于密钥进行加密是行不通了,单纯的只使用对称加密也是行不通的。
方案二:只使用非对称加密
由于非对称加密的机制,如果服务器将公钥以明文的方式传输给客户端,之后客户端向服务器传数据之前都先使用这个公钥加密好之后在传输,从客户端到服务端似乎是安全了(因为只有服务器有对应的私钥能解开公钥加密的数据)
但是服务器到客户端这条路并不能保证安全
如果服务器使用它的私钥加密数据给客户端,那么客户端可以使用公钥来解密它,而这个公钥是一开始通过明文传输给浏览器的,如果这个公钥被中间人劫持到了,那他也能用该公钥解密服务器传来的信息了
方案三:双方都使用对称加密
步骤:
- 服务端有自己的私钥S和公钥S‘,客户端有自己的私钥C和公钥C’
- 双方交换公钥
- 客户端向服务端发消息时:先将消息经过交换过来的公钥S‘加密,然后通过中间人发到服务端,然后服务端通过自己的私钥S解密,得到明文信息
- 服务端向客户端发消息时,同样先将消息经过交换过来的公钥C’加密,然后通过中间人发到客户端,然后客户端通过自己的私钥C解密,得到明文信息
以上操作步骤看似可行,但是还是存在弊端
- 双方通信一直使用对称加密导致效率太低
- 安全性依然存在问题(之后解释)
方案四:非对称加密 + 对称加密
步骤:
- 服务端有自己的私钥S和公钥S‘
- 客户端向服务端发起http请求,获得服务端的公钥S’
- 客户端在自己本地生成对称密钥X,并将密钥X通过公钥S‘进行加密之后发送给服务端(此时只有服务器端有私钥S,即只有服务器端可以对加密后的密钥X进行解密)
- 服务端收到加密后的密钥X并对其进行解密得到密钥X
- 双方以后通信时就只用使用密钥X进行加密和解密的操作即可
虽然以上方案看似可行,但是都存在一个问题:如果中间人一开始就已经开始攻击了呢?
中间人攻击
就以方案四为例
- 服务端有自己的私钥S和公钥S’
- 中间人有自己的私钥M和公钥M‘
- 客户端向服务端发起请求,请求服务端的公钥S‘
- 服务端向客户端发送公钥S’,经过中间人时,中间人也能获取到公钥S‘,并将公钥S’替换成自己的公钥M‘重新发送到客户端
- 客户端接收到中间人的公钥M’,同时自己生成一个密钥X,用公钥M‘对密钥X进行加密并发送给服务端
- 加密的密钥X再次经过中间人之后,由于密钥X是被中间人自己的公钥M’加密的,所以中间人自己也可以使用私钥M’对密钥进行解密,得到密钥X。然后中间人利用最开始获取到的公钥S‘对该密钥进行加密(确保服务端可以成功解密),然后发送到服务端
- 服务端获取到密钥X对其成功解密后,以后服务端和客户端之间的消息都是被密钥X来进行加密和解密的,由于中间人也拥有了密钥X,所以中间人可以劫持数据,进行窃听甚至修改。
以上的方案同样可以适用于方案二和方案三,问题的本质就在于客户端无法判断自己收到密钥是否真的是服务端发过来的而不是被篡改过的
如何确认密钥是否被修改
理解数据签名
从上图可以得知,数据经过散列函数之后形成的散列值需要经过签名者的私钥加密之后形成签名,在发送数据之前会将数据和签名放在一起发送出去。在接收者一方,接收到数据和签名之后,先使用签名者将签名解密得到散列值,并对数据重新经过散列函数运算得到散列值,将这两个散列值进行比较,如果两个散列值相同,则说明数据并没有被修改,反之则说明被中间人修改了
由于解密的一方只会使用签名者的公钥解密,且中间人无法得到签名者的私钥,所以中间人也无法蒙混过去
而这个签名者在这里指的是CA机构
CA认证
服务端在使用 HTTPS 前,需要向 CA 机构申领一份数字证书,数字证书里含有证书申
请者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明服务端公钥的权威性。以下就是CA认证的过程
客户端的第一次请求,不仅仅得到了服务端传来的公钥S,实际上,客户端得到的是一个证书,该证书里包含了服务器的域名、公钥等信息,为了证明该证书没有被别人篡改过,它还携带了签名(所有的浏览器(客户端),一般都会内置可信的CA机构或者授权的子机构的公钥)。
方案五:非对称加密 + 对称加密 + 证书认证
- 在客户端和服务端建立通信之初,服务端先向客户端发起一个证书,该证书内包含了服务端的公钥以及服务端的相关信息,当然也包含了签名
- 客户端收到证书之后,会使用内置的CA机构的公钥对签名进行解密得到散列值,并对证书的其他数据通过哈希函数得到散列值,通过将两个散列值进行比对验证证书内容是否被篡改过
- 若验证成功,客户端拿到了服务端发来的公钥,同时自己生成一个密钥X,通过服务端发来的公钥对密钥X进行加密并发送会服务端(由于只有服务端才能解密,所以发送过程中是安全的)
- 服务端拿到X,自此之后,双方通过密钥X来进行加密和解密的操作
补充
如何生成CSR和密钥
在线生成CSR和私钥:https://myssl.com/csr_create.html
查看浏览器的受信任证书发布机构
以Edge浏览器为例
点击右上角三个点,点击设置
点开就是了