为什么要用 HTTPS
HTTP 是明文传输,任何人都能窃听到,甚至篡改。
HTTPS 可以有效防止窃听和篡改,能极大提高网站的安全性。
HTTPS 如何保障安全性
加密传输数据
HTTPS 会先将数据进行加密再传输,在网络中传输的时候任何人都只能捕获到加密后的数据。而只有拥有相应的秘钥才能解开数据。
那这里就有了新的问题:数据要怎么加密,用哪种加密方法来加密,客户端和服务端怎么协商确定秘钥,同时保证秘钥不被第三方所知道。
对称加密与非对称加密
先简单介绍两种加密的方式:对称加密和非对称加密。
顾名思义,对称加密就是加密和解密时使用的是相同的秘钥,优点是速度快。缺点是任意两个通信的实体之间都要维护他们彼此间通信的秘钥,而维护这么多的秘钥的成本太大了。
非对称加密就是加密和解密使用的是不同的秘钥,分别称之为公钥和私钥。公钥可以公开出来让所有人知道;私钥必须保存好,不能让其他人知道。非对称加密的特点是用公钥加密的数据只能用私钥解密,用私钥加密的数据只能用公钥解密。缺点是速度慢。
于是,我们可以这样操作:
客户端随机生成一个秘钥 A,使用服务端的公钥加密后发送给服务端。
服务端收到后,用自己的私钥进行解密获得 A。
服务端告诉客户端自己已经获得了 A。
这样客户端和服务端就都得到了一个秘钥 A,且不为其他人所知。
秘钥 A 只在本次通信过程中有效。
随后客户端每次发送数据前,都用秘钥 A 进行对称加密,服务端收到后都用秘钥 A 进行解密。
服务端发送数据给客户端时,也采用类似的操作。
通过这样的操作,我们利用非对称加密来达到协商和确定好对称加密的秘钥 A,同时又利用了对称加密速度快的特点。
实际上 HTTPS 协商秘钥 A 的过程会比这个更复杂。但本质都是利用非对称加密来达到协商的目的。
这里实际上就有了一个新的问题:客户端怎么拿到服务端的公钥,同时确保这就是服务端的公钥而不是其他人伪造的。
HTTPS 证书
当我们访问一个 HTTPS 的网站时,服务端会下发一个 HTTPS 证书给我们。证书里面就包含了服务端的公钥,同时还有其他信息:证书所属的域名、颁发的机构、何时生效、何时过期等。
那现在问题就是我们如何确认一个证书是不是有效的,而且是不是我们访问的服务端发给我们的。
这里就牵扯到了 HTTPS 证书的生成。
简单说明一下 CA(证书颁发机构),CA 专门管理证书的申请和颁发。
申请证书的过程如下:
服务端向 CA 申请自己的 HTTPS 证书,
CA 审核通过后,就会将服务端的域名、公钥、证书的有效期等信息写到证书里。
同时 CA 会对证书里的信息做一个哈希获得一个哈希值,
用自己的秘钥对这个哈希值进行加密获得一个加密串,
并把加密串也写到证书里。这一过程称之为签名。
(签名就是证明这证书的确是 CA 发的,CA 为证书进行背书。)
现在,当我们访问网站后收到一个证书时,
首先用 CA 的公钥对加密串进行解密,得到加密前的哈希值。
再对证书本身的数据做一个哈希,如果这两个哈希值是一致的说明证书有效。
同时还要注意证书是否在有效期内。
通过以上校验,我们就可以认为这的确是我们期望的服务端下发的证书。
假设有人伪造了证书,假装自己是服务端,
由于他没有 CA 的秘钥,也就无法构造出与伪造数据吻合的加密串。
我们只要用 CA 的公钥对加密串一解密,发现哈希值不一致,就可以认定这是伪造的。
这里又牵出了新的问题:我们怎么拿到 CA 的公钥。
全球只有为数不多的几个顶级 CA 有资格进行 HTTPS 证书的颁发。
所以操作系统和浏览器会预装这些 CA 的证书(包含了 CA 的公钥)。也就省去我们获取 CA 公钥的步骤和获取过程可能存在的伪造。
这里也可以看出 CA 证书是多么重要。如果我们电脑中安装了恶意的 CA 证书,而这个 CA 又故意或无意签发了大量恶意服务端的证书,那我们即便使用了 HTTPS 也无法保证安全通信。
客户端证书
大部分时候,我们都是从服务端拿数据,所以主要保证服务端是我们要访问的,也就是服务端要配置 HTTPS 证书。
如果为了让服务端确认客户端的确是谁,在大多数情况下使用“账号+密码”或“手机号+短信验证码”已经足够了。
为每个客户端都配置 HTTPS 证书,一个是申请证书本身需要费用;一个是申请的门槛较高,不是每个用户都能做到。
也因此,只要服务端配置了 HTTPS 证书,在大多数情况下已经足够安全了。
但是,对于某些对安全性要求极高的网站来说,他们也会要求客户端要安装 HTTPS 证书。
比如银行网上转账就是一个十分敏感的操作。通常在我们申请银行卡的时候会得到一个 U 盾。
U 盾里面实际上也是一个 HTTPS 证书,用于证明“我就是我”。
只是这个证书是由银行自己颁发的。(实际上要像 CA 那样发布证书是很容易的,但是只有少数权威的 CA 才被操作系统和浏览器所认可。)
当我们要进行网上转账的时候,就必须把 U 盾插入到电脑上,访问银行的相关网站时,就会把 U 盾中的证书带上去。
银行的服务端在收到我们的证书,就用自己的私钥进行解密,也就能确认我们的身份了。
Ref
深入浅出 HTTPS