HTTPS 原理
HTTPS 的存在主要原因是由于 HTTP 的不安全导致的:
- 无法保证消息的保密性。
- 无法保证消息的完整性和准确性。
- 无法保证消息来源的可靠性。
因此 HTTP 如果受到中间人攻击,那么攻击者可以随意处理数据并发送虚假的数据给服务器,这样安全性就没有保障了。
加密原理
在说 HTTPS 加密原理之前,先说下明文、密文、加密、解密的概念:
- 明文(Plaintext),一般认为明文是有意义的字符或者比特集,或者是通过某种公开编码就能获得的消息。明文通常用 m 或 p 表示。
- 密文(Ciphertext),对明文进行某种加密后就变成了密文。
- 加密(Encrypt),把原始的信息(明文)转换为密文的信息变换过程。
- 解密(Decrypt),把已经加密的信息恢复成明文的过程。
对称加密
对称加密就是客户端和服务器公用一个密匙用来对消息加解密。客户端和服务器约定好一个加密的密匙。客户端在发消息前用该密匙对消息加密,发送给服务器后,服务器再用该密匙进行解密拿到消息。
常见的对称加密算法有 AES-CBC、DES、3DES、AES-GCM 等。
对称加密的优势是信息传输 1 对 1,需要共享相同的密码,密码的安全是保证信息安全的基础,服务器和 N 个客户端通信,需要维持 N 个密码记录,且缺少修改密码的机制。
这种加密方式比较简单,能够加密 HTTP 报文内容,但由于密钥会一起发送给对方,如果中途密钥泄露,那么这些加密就都是形同虚设了。
对称加密算法公开、计算量小、加密速度快、加密效率高,适合对大量数据进行加密的场景。
非对称加密
非对称加密也称为公钥加密,分为两个密钥:公钥和私钥,公钥进行加密,私钥进行解密,客户端和服务端均拥有一个公有密匙和一个私有密匙。公有密匙可以对外暴露,而私有密匙只有自己可见。信息传输关系为 1 对 N,客户端共享公钥,服务器掌握私钥
使用公钥加密的文本只能使用私钥解密,同时,使用私钥加密的文本也可以使用公钥解密。
非对称加密算法的设计要比对称算法难得多,常见的比如 DH、DSA、RSA、ECC 等。
非对称加密使得私有密钥泄露的风险降低,因为公匙加密的消息只有对应的私匙才能解开,所以较大程度上保证了消息的来源性以及消息的准确性和完整性。
非对称加密的缺点在于在中间人攻击下,攻击者获取了公钥,可以把公钥替换成自己的发给服务器,服务器也无法判断公钥来源的准确性。或者中间人可以直接篡改请求信息再用公钥加密,服务器用私钥解密后将得到错误的信息,因此非对称加密仍然没有解决信息的安全性和准确性。
此外,非对称加密的性能相对对称加密来说会慢上几倍甚至几百倍,比较消耗系统资源,只适合对少量数据进行加密。
混合加密
混合加密是结合对称加密和非对称加密各自优点的一种加密方式。其具体的实现思路是先使用对称加密算法对数据进行加密,然后使用非对称加密算法对对称加密的密钥进行非对称加密,之后再把加密后的密钥和加密后的数据发送给接收方。
由于对称加密会暴露密钥,被中间人获取后可以轻而易举地解密出请求信息,因此对密钥采用非对称加密,由于没有私钥,中间人无法得到真实的密钥信息。而数据本身依然采用对称加密,服务端用私钥解密得到密钥后解密数据即可。这样既可以提升性能,又能保证数据的安全性和准确性。
现在我们使用混合加密的方式实现了机密性,是不是就能够安全的传输数据了呢?还不够,在机密性的基础上还要加上完整性、身份认证的特性,才能实现真正的安全。而实现完整性的主要手段是摘要算法(Digest Algorithm)。
摘要算法
可以把摘要算法理解成一种特殊的压缩算法,它能够把任意长度的数据压缩成一种固定长度的字符串,这就好像是给数据加了一把锁。MD5 就是这样的算法。
摘要算法是散列算法,没有所谓的 “加密” 、“解密” 的说法,这些算法是单向的,没有密钥可以将其恢复为加密之前的内容,这些说法其实都是不严谨的,虽然在很多书上都说这么描述的。
这类算法如 MD5 通常用于校验文件的完整性,还用于其他安全协议和应用程序中,例如 SSH、SSL 和 IPSec。一些应用程序通过向明文加盐值或多次应用哈希函数来增强 MD5 算法。
由于 MD5 是基于明文的算法,因此理论上完全可以暴力破解逆推得出原文内容,很多程序现在通过加盐来增强安全性。也就是在原本的内容后加上一段随机字符串再进行转换。
SHA-1 和 MD5 非常相似,只是 SHA-1 得出的结果集要比 MD5 高出几个数量级,因此更加安全。
SHA-2 它在 SHA-1 的基础上做了重大的修改,SHA-2 系列包含六个哈希函数,其摘要(哈希值)分别为 224、256、384 或 512 位:SHA-224, SHA-256, SHA-384, SHA-512。分别能够生成 28 字节、32 字节、48 字节、64 字节的摘要。
有了 SHA-2 的保护,就能够实现数据的完整性,哪怕你在文件中改变一个标点符号,增加一个空格,生成的文件摘要也会完全不同,不过 SHA-2 是基于明文的摘要算法,还是不够安全,那应该用什么呢?
散列算法只可以验证数据的完整性,但是无法保证数据防篡改。
MAC 算法
MAC 算法除了验证完整性,还可以确保数据的源头正确。MAC 值一般和原始消息一起传输,原始消息可以选择加密,也可以选择不加密,通信双方会以相同的方式生成 MAC 值,然后进行比较,一旦两个 MAC 值相同表示 MAC 验证正确,否则验证失败。
在密码学中,MAC 算法有两种形式,分别是 CBC-MAC 算法和 HMAC 算法。在 HTTP 中应用最多的 MAC 算法是 HMAC 算法。
HMAC 算法使用散列算法作为加密基元,HMAC 结合散列算法有多种变种,比如 HMAC-SHA-1、HMAC-SHA256、HMAC-SHA512。不要误以为 HMAC 算法就是散列算法加上一个密钥,HMAC 算法虽然是基于散列算法的,但内部的实现还是相当复杂的。
HTTPS 和 HTTP 的区别
- HTTP 是超文本传输协议,信息是明文传输,HTTPS 协议要比 HTTP 协议安全,HTTPS 是具有安全性的 ssl 加密传输协议,可防止数据在传输过程中被窃取、改变,确保数据的完整性(当然这种安全性并非绝对的,对于更深入的 Web 安全问题,此处暂且不表)。
- HTTP 协议的默认端口为 80,HTTPS 的默认端口为 443。
- HTTP 的连接很简单,是无状态的。HTTPS 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20% 的耗电。
- HTTPS 缓存不如 HTTP 高效,会增加数据开销。
- HTTPS 协议需要 ca 证书,费用较高,功能越强大的证书费用越高。
- SSL 证书需要绑定 IP,不能再同一个 IP 上绑定多个域名,IPV4 资源支持不了这种消耗。
不过最大的不同就是:HTTPS 比 HTTP 多了一层 TLS/SSL 协议。通常情况下,HTTP 会先直接和 TCP 进行通信。在使用 SSL 的 HTTPS 后,则会先演变为和 SSL 进行通信,然后再由 SSL 和 TCP 进行通信。也就是说,HTTPS 就是身披了一层 TLS/SSL 的 HTTP。
HTTPS 协议提供了三个关键的指标:
- 加密(Encryption), HTTPS 通过对数据加密来使其免受窃听者对数据的监听,这就意味着当用户在浏览网站时,没有人能够监听他和网站之间的信息交换,或者跟踪用户的活动,访问记录等,从而窃取用户信息。
- 数据一致性(Data integrity),数据在传输的过程中不会被窃听者所修改,用户发送的数据会完整的传输到服务端,保证用户发的是什么,服务器接收的就是什么。
- 身份认证(Authentication),是指确认对方的真实身份,也就是证明你是你(可以比作人脸识别),它可以防止中间人攻击并建立用户信任。
TLS/SSL 是一个独立的协议,不只有 HTTP 可以使用,其他应用层协议也可以使用,比如 SMTP(电子邮件协议)、Telnet(远程登录协议) 等都可以使用。
下面我们说说 TLS/SSL 协议的工作原理。
TLS/SSL 工作原理
TLS/SSL 的功能实现主要依赖于三类基本算法:散列算法、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列算法验证信息的完整性。
SSL/TLS 握手过程
第一次握手:ClientHello
客户端提供的信息:
- 支持的协议版本,比如 TLS 1.0 版。
- 客户端生成的随机数,稍后用于生成“对话密钥”。
- 支持的加密算法,比如 RSA 公钥加密。
- 支持的压缩方法。
这里注意客户端发送的信息中不包含服务器的域名。也就是说理论上服务器只能包含一个网站,否则会分不清楚应该向客户端提供哪个网站的数字证书,这就是为什么通常一台服务器只能有一张数字证书发原因。
第二次握手:ServerHello
服务器响应信息:
- 确认使用的加密通信协议版本,比如 TLS 1.0。如果浏览器与服务器支持的版本不一致,则服务器关闭加密通信。
- 服务器生成的随机数,稍后用于生成“对话密钥”。
- 确认使用的加密方法,比如 RSA 公钥加密。
- 服务器证书。
- 客户端证书请求(如果服务器需要确认客户端的身份,如金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供 USB 密钥,里边就包含一张客户端证书)。
第三次握手:客户端回应
客户收到服务器回应后,首先验证服务器证书。如果证书不是可信的 CA 机构颁布或者证书中的域名与实际域名不一致或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
如果证书没有问题,客户端就会从证书中取出服务器的公钥,然后向服务器发送下面三项信息。
- 客户端生成的随机数。该随机数用服务器公钥加密,防止被窃听。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供服务器检验。
- 客户端证书(如果前一步,服务器要求客户端证书)。
上面第一项的随机数是整个握手阶段出现的第三个随机数,又称“pre-master key”。所以客户端和服务端同时有了三个随机数,接着双方就用实现商定的加密方法,各自生成本次会话所用的同一把“会话密钥”。
为什么一定要用三个随机数来生成“会话密钥”?
pre master 的存在在于 SSL 协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre master secret 就有可能被猜测出来,那么仅仅用 pre master secret 做为密钥就不和适了,因此必须引入新的随机因素。所以客户端和服务端加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出来了,一个伪随机可能不完全随机,可是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。这里注意,因为第一个和第二个随机数都是明文传输的,如果客户端随机是一个伪随机,那么第三方通过第一个随机数猜出 pre master key 的几率就大大增加,所以用三个随机数混合加密出一个“会话密钥”。
第四次握手:服务器的最后回应
服务器收到客户端的第三个随机数 pre-master key 之后,计算生成本次会话所用的”会话密钥”。然后,向客户端最后发送下面信息:
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的 hash 值,用来供客户端校验。
至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用”会话密钥”加密内容。
HTTPS 协议的工作原理
综上所述,客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤:
- 客户端使用 HTTPS url 访问服务器,则要求 web 服务器建立 ssl 链接。
- web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),传输给客户端。
- 客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级。
- 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
- web 服务器通过自己的私钥解密出会话密钥。
- web 服务器通过会话密钥加密与客户端之间的通信。
PKI
上面我们说到 RSA 算法是非对称加密算法的一种,虽然可用来进行身份验证,但要求的前提是合法的服务器掌握着对应的私钥。但 RSA 算法无法确保服务器身份的合法性,因为公钥并不包含服务器的信息,存在安全隐患:
- 客户端 C 和服务器 S 进行通信,中间节点 M 截获了二者的通信;
- 节点 M 自己计算产生一对公钥 pub_M 和私钥 pri_M;
- C 向 S 请求公钥时,M 把自己的公钥 pub_M 发给了 C;
- C 使用公钥 pub_M 加密的数据能够被 M 解密,因为 M 掌握对应的私钥 pri_M,而 C 无法根据公钥信息判断服务器的身份,从而 C 和 * M 之间建立了"可信"加密连接;
- 中间节点 M 和服务器 S 之间再建立合法的连接,因此 C 和 S 之间通信被 M 完全掌握,M 可以进行信息的窃听、篡改等操作。
- 另外,服务器也可以对自己的发出的信息进行否认,不承认相关信息是自己发出。
数字签名与数字证书
非对称加密虽然能确保加密文件内容不被窃取,但不能保证文件不被篡改。数字签名就是用来验证文件是否被篡改过。
数字签名就是一个文件经过摘要算法转换后的信息,再使用服务器的私钥进行加密后的结果。数字签名是和源文件一起发送给接收方的,接收方收到后使用收到的公钥进行解密,再对文件用摘要算法算出一个摘要,然后和数字签名中的摘要进行比对,两者不一致的话说明文件被篡改了。
但这里还有一个问题,我们无法确定公钥是否为信息的发送者所发出。因此,就算公开密钥被第三者恶意替换,接收方也不会注意到。数字证书可以完美的解决这一问题,保证公开密钥的正确性。
数字证书是一个经证书授权中心生成的文件,数字证书里一般会包含公钥(私钥保存在服务器)、公钥拥有者名称、CA 的数字签名、有效期、授权中心名称、证书序列号等信息。其中 CA 的数字签名是验证证书是否被篡改的关键,它其实就是对证书里面除了 CA 的数字签名以外的内容进行摘要算法得到一个摘要,然后 CA 机构用他自己的私钥对这个摘要进行加密就生成了 CA 的数字签名,CA 机构会公开它的公钥,验证证书时就是用这个公钥解密 CA 的数字签名,然后用来验证证书是否被篡改。
因此解决上述身份验证问题的关键是确保获取的公钥途径是合法的,能够验证服务器的身份信息,为此需要引入权威的第三方机构 CA(如沃通 CA)。CA 负责核实公钥的拥有者的信息,并颁发认证"证书",同时能够为使用者提供证书验证服务,即 PKI 体系(PKI 基础知识)。
基本的原理为,CA 负责审核信息,然后对关键信息利用私钥进行"签名",公开对应的公钥,客户端可以利用公钥验证签名。CA 也可以吊销已经签发的证书,基本的方式包括两类 CRL 文件和 OCSP。CA 使用具体的流程如下:
- 服务方 S 向第三方机构 CA 提交公钥、组织信息、个人信息(域名)等信息并申请认证;
- CA 通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
- 如信息审核通过,CA 会向申请者签发认证文件-证书。证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文,同时包含一个签名;签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA 的私钥对信息摘要进行加密,密文即签名;
- 客户端 C 向服务器 S 发出请求时,S 返回证书文件;
- 客户端 C 读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA 的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即公钥合法;
- 客户端然后验证证书相关的域名信息、有效时间等信息;
- 客户端会内置信任 CA 的证书信息(包含公钥),如果 CA 不被信任,则找不到对应 CA 的证书,证书也会被判定非法。
这里需要注意:
- 申请证书不需要提供私钥,确保私钥永远只能服务器掌握;
- 证书的合法性仍然依赖于非对称加密算法,证书主要是增加了服务器信息以及签名;
- 内置 CA 对应的证书称为根证书,颁发者和使用者相同,自己为自己签名,即自签名证书(为什么说"部署自签 SSL 证书非常不安全")
- 证书=公钥+申请者与颁发者信息+签名;