前言:前段时间被问到HTTPS的相关问题,由于离看相关问题的时间很久了再加上自己也没有实践过,很多点没有说出来,因此特地又温习了一遍相关的知识,特此记录下来以加强记忆
什么是HTTPS
我们知道HTTP是一种无状态、明文的网络传输协议,目前我们浏览的很多网站都是基于这种协议进行客户端和服务端信息交互的。但是由于HTTP明文传输的特点,很容易导致信息在传输过程中被截获甚至被篡改造成严重的后果。在信息安全挑战越来越频繁的情景下,信息保护的需求越来越急迫。目前保护信息安全最常见和普及的就是加密技术,根据加密对象的不同可以分为两种。
-
通信加密
顾名思义就是对通信进行加密,HTTP协议本身没有加密的机制,但是可以通过和SSL的组合使用来达到加密通信通道的效果,在使用SSL建立安全的通信线路之后就可以在在这条线路上使用HTTP协议通信了,于SSL组合使用的HTTP协议就被成为HTTPS。 -
内容加密
另一种加密的方式就是对通信的内容本身进行加密,即把HTTP报文里面的内容加密处理后在进行传输,无论是客户端还是服务端都需要对报文进行加密后再发送,同理两端接收到的都是加密之后的报文,需要先对报文进行解密才能拿到真正的报文内容。这就要求客户端和服务器端都要具有加解密的能力。这种方式可以防止通信内容被窃取但是无法阻止内容被篡改。
进一步了解前的准备知识
加密算法
近代的加密方法中加密算法是公开的,而密钥是保密的,通过这种方式得以保持加密算法的安全性。
对称加密
加密解密使用同一个密钥的加密方式称之为对称密钥加密也被称为共享密钥加密。这种加密方式需要对密钥特别保护,只要密钥被窃取,信息就会完全暴露。在互联网环境下,很难保证共享密钥的安全性,如果在发送共享密钥的过程中通信被监听,密钥就会落在攻击者手中,那么信息加密也就失去了意义。非对称加密
非对称加密方法有两个密钥,一个是公开密钥另一个是私有密钥。公开密钥可以随意发布,任何人都可以获取公开密钥,私有密钥只有信息接收方知道。
使用非对称加密方式,发送的密文的一方使用接收方的公开密钥进行加密处理,接收方收到密文后再使用私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也就不需要担心密钥被攻击者窃取。另外,想要根据密文和公开密钥恢复原文是很困难的,就目前的技术看来说很难办到,就算能做到,付出的价值也会让攻击者得不偿失。但是非对称加密相对对称加密速度要慢很多。
签名和证书
数字签名
数字签名就是在信息的后面再加上一段内容,可以证明信息没有被修改过,怎么样可以达到这个效果呢?一般是对信息做一个HASH计算得到一个HASH值,注意,这个过程是不可逆的,也就是说无法通过HASH值得出原来的信息内容。在把信息发送出去时,把这个HASH值加密后做为一个签名和信息一起发出去。 接收方在收到信息后,会重新计算信息的HASH值,并和信息所附带的HASH值(解密后得到)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里HASH计算可以保证不同的内容一定会得到不同的HASH值,所以只要内容一被修改,根据信息内容计算的HASH值就会变化。当然,不怀好意的人也可以修改信息内容的同时也修改HASH值,从而让它们可以相匹配,为了防止这种情况,HASH值一般都会加密后(也就是签名)再和信息一起发送,以保证这个HASH值不被修改数字证书
数字证书是由公认的权威公正性第三方机构(即CA中心)签发的证书。数字证书一般包含以下主要内容:
证书的发布机构
证书的有效期
公钥
证书所有者(Subject)
签名所使用的算法
指纹以及指纹算法
数字证书的作用基本可以概括为:数字证书可以保证数字证书里的公钥确实是这个证书的所有者(Subject)的,或者证书可以用来确认对方的身份。
数字证书首先由证书的发布机构制作发布具有一定的有效期限,过期后的证书不再具有安全效力。证书中的公钥为证书发布机构的公钥,和证书的签名、指纹一起作用来确定证书的完整性,确保证书没有被篡改过。
为了保证证书的安全,证书发布机构在发布证书之前会对整个证书做一次HASH计算(此处的HASH算法即为证书中的指纹算法),并对得出的HASH值(指纹)做一次签名加密(证书发布机构使用自己的私钥以及证书中的签名算法加密),并将签名和证书放在一起发布。使用者在打开这个证书的时候会使用证书中的公钥和签名算法解出签名加密的指纹,假设指纹为1,然后使用者会使用证书中声明的指纹算法对整个证书做一次计算得出指纹2,最后比较指纹1和2是否相等,如果相等则可以保证证书完整性,证书没有被中途篡改。
注意:以上只能证实证书的完整性,并不能保证证书被整个替换掉,所以为了解决这种问题,数字证书的发布机构也有自己的证书来保证自己的真实性。那么证书发布机构的证书是哪里来的呢?原来这种证书会默认安装在操作系统中,像微软、苹果等操作系统公司会根据一些权威安全机构的评估选取一些信誉很好并且通过一定的安全认证的证书发布机构,把这些证书发布机构的证书默认就安装在操作系统里面了,并且设置为操作系统信任的数字证书。这些证书发布机构自己持有与他自己的数字证书对应的私钥,他会用这个私钥加密所有他发布的证书的指纹作为数字签名。
HTTPS的工作流程
准备阶段
- 服务端
服务端把自己的公钥登录至数字证书发布机构,数字证书发布机构使用自己的私钥对服务端的公钥做签名加密并颁发此公钥的证书。 - 客户端
此处的客户端一般是指浏览器,浏览器会事先内置大部分权威机构的公钥数字证书。如果没有该机构的公钥数字证书则需要去该机构处下载安装该证书,当然这样做需要承担一定的风险。
通信阶段
客户端和服务端协商
- 客户端通过发送Client Hello报文开始SSL通信。报文中 包含客户端支持的 SSL 的指定版本、加密件(Cipher Suite)表,里面包含所支持使用的加密算法及密钥长度等。
- 服务端接收到客户端所有的Cipher后与自身支持的对比,如果不支持则连接断开,反之则会从中选出一种加密算法和HASH算法以证书的形式返回给客户端,以Server Hello报文作为响应 。
- 之后服务端发送Certificate报文,报文中包含公钥证书。
- 最后服务端发送Server Hello Done报文通知客户端,最初段的 SSL 握手协商部分结束。
客户端生成随机密码
- 客户端检查颁发证书的机构是否合法与是否过期,证书中包含的网站地址是否与正在访问的地址一致等。
- 如果证书验证通过,客户端会生成一串随机数即PreMaster Secret,然后用证书中的公钥和加密算法对PreMaster Secret加密,以Client Key Echange报文形式发送给服务端。
- 用证书的HASH算法把握手消息取HASH值,然后用PreMaster Secret加密 “握手消息+握手消息HASH值”,以Change Cipher Spec报文形式发送给服务端,该报文会提示服务端在此报文之后的通信会用Pre-master secret加密。
- 客户端发送Finished报文,该报文包含接今全部报文的整体校验值,这握手协是否能成功,要以服务端是否能正确解密该报文作为判定标准。
服务端确认随机密码
- 服务端拿到客户端传来的密文,用自己的私钥取出PreMaster Secret,再用PreMaster Secret解密握手消息和握手消息的HASH值,并与自己计算的握手消息HASH值做对比确认是否一致,如果一致则表明握手消息在传输过程中没有被篡改,然后服务端同样发送Change Cipher Spec形式的报文。
- 服务器同样发送Finished报文。
正式通信
- 客户端用随机数解密报文并计算握手消息的HASH,如果与服务端发来的HASH一致则至此握手过程结束,SSL连接就建立完成,之后所有的通信数据将由之前客户端生成的随机密码利用对称加密算法进行加密。
- 开始进行应用协议的通信,客户端发送HTTP请求。
- 应用协议通信,即发送 HTTP 响应。
- 最后由客户端断开接,断开接时,发送 close_notify报文。
为什么需要数字证书
因为由于加密算法是公开的,大家都可以生成自己的公钥和私钥,为了防止攻击者冒充服务端做中间人攻击,就需要一种手段证明通信方是预期的安全对象,因此需要数字证书。如果没有数字证书,攻击者很容易做出如下例子的攻击:
// 黑客截获“客户”发给“服务器”的消息
“客户”->“黑客”:你好
// 黑客自己生成一对公钥和私钥,把公钥发给“客户”,自己保留私钥
“黑客”->“客户”:你好,我是服务器,这个是我的公钥
“客户”->“黑客”:向我证明你就是服务器
// 客户收到“黑客”用私钥加密的信息后,是可以用“黑客”发给自己的公钥解密的,从而会误认为“黑客”是“服务器”
“黑客”->“客户”:你好,我是服务器
为什么需要生成对称密钥通信
因为服务端的公钥是公开的,如果服务端直接使用私钥加密报文通信是无法保证报文能安全的到达客户端的。而且非对称加密的耗时较长,通信效率不如对称加密。