1. HTTPS
Secure Hypertext Transfer Protocol, 安全超文本传输协议.
是使用 TLS/SSL 加密的 HTTP 协议, 是 HTTP 的安全版.
2. TLS/SSL
TLS/SSL 协议, 即安全传输层协议, 是介于 TCP 和 HTTP 之间的一层安全协议, 不影响原有的 TCP 协议和 HTTP 协议.
TLS/SSL 协议提供服务的主要有:
- 身份验证, 防止劫持
- 信息加密, 防止窃听
- 完整性效验, 防止篡改
TLS/SSL 可分为2层:
- Record Protocol, 记录协议
它建立在可靠的传输协议之上, 如 TCP 协议, 为高层协议提供数据封装, 压缩, 加密等基本功能的支持.
主要用来定义传输的格式.
- Handshake Protocol, 握手协议
它建立在SSL记录协议之上, 用于在实际的传输开始前, 通信双方进行身份认证, 协商加密算法, 交换加密密钥等.
主要用来协商出一份密钥.
2.1. TLS/SSL 工作原理
TLS/SSL的功能实现主要依赖于三类基本算法: 散列函数 Hash, 对称加密和非对称加密, 其利用非对称加密实现身份认证和密钥协商, 对称加密算法采用协商的密钥对数据加密, 基于散列函数验证信息的完整性.
2.1.1. 非对称加密
即常见的 RSA 算法, 还包括 ECC, DH 等算法.
算法特点是, 密钥成对出现, 一般称为公钥(公开)和私钥(保密), 公钥加密的信息只能私钥解开, 私钥加密的信息只能公钥解开.
因此掌握公钥的不同客户端之间不能互相解密信息, 只能和掌握私钥的服务器进行加密通信, 服务器可以实现1对多的通信, 客户端也可以用来验证掌握私钥的服务器身份.
非对称加密的特点是信息传输1对多, 服务器只需要维持一个私钥就能够和多个客户端进行加密通信, 但服务器发出的信息能够被所有的客户端解密, 且该算法的计算复杂, 加密速度慢.
2.1.2. 对称加密
常见的有 AES-CBC, DES, 3DES, AES-GCM等, 相同的密钥可以用于信息的加密和解密, 掌握密钥才能获取信息, 能够防止信息窃听, 通信方式是1对1.
对称加密的优势是信息传输1对1, 需要共享相同的密码, 密码的安全是保证信息安全的基础, 服务器和 N 个客户端通信, 需要维持 N 个密码记录, 且缺少修改密码的机制.
2.1.3. 散列函数 Hash
常见的有 MD5, SHA1, SHA256, 该类函数特点是函数单向不可逆, 对输入非常敏感, 输出长度固定, 针对数据的任何修改都会改变散列函数的结果, 用于防止信息篡改并验证数据的完整性.
在信息传输过程中, 散列函数不能单独实现信息防篡改, 因为明文传输, 中间人可以修改信息之后重新计算信息摘要, 因此需要对传输的信息以及信息摘要进行加密.
结合三类算法的特点, TLS的基本工作方式是, 客户端使用非对称加密与服务器进行通信, 实现身份验证并协商对称加密使用的密钥, 然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信, 不同的节点之间采用的对称密钥不同, 从而可以保证信息只能通信双方获取.
2.2. TLS/SSL 握手过程
2.2.1. 客户端发起请求
Client Hello
客户端发起请求, 以明文传输请求信息, 包含信息有:
- version: 当前支持的最后TLS协议版本
- cipher suites: 客户端支持的加密套件列表
每个加密条件对应4个功能组合:
- Au, 认证算法, 用于身份认证
- Key Exchange, 密钥交换算法, 用于密钥协商
- Enc, 对称加密算法, 用于信息加密
- Mac, 信息摘要算法, 用于完整性效验
- compression methods: 支持的压缩算法列表, 用于后续的信息压缩传输
- random_client: 用于后续的密钥生成
- extensions: 扩展字段, 支持协议与算法的相关参数及其他辅助信息等, 如常见的SNI
2.2.2. 服务器端回应
2.2.2.1. Server Hello
服务端返回协商的结果, 包含信息有:
- version: 使用的协议版本
- cipher suite: 选择的加密套件
- compression method: 选择的压缩算法
- random_server: 用于后续的密钥生成
2.2.2.2. Server Certificate
服务端配置对应的证书链发送给客户端, 用于身份效验与密钥交换.
2.2.2.3. Server Hello Done
服务端通知客户端 Server Hello 发送结束.
2.2.2.4. Client Certificate Request
对于非常重要的信息, 服务端需要对客户端进行验证, 保证数据传送给了安全合法的客户端.
服务端发送 client_certificate_request 标识, 请求验证客户端证书.
2.2.3. 客户端验证证书
Certificate Verify
客户端验证证书合法性.
如果验证通过才会进行后续通信, 否则根据错误情况不同做出提示和操作.
- 证书链的可信性 trusted certificate path
- 证书是否被吊销 revocation
- 有效期 expiry date
- 域名 domain
2.2.4. 客户端回应
2.2.4.1. Client Certificate
如果服务端需要验证客户端证书, 即双向认证.
认证方式基本相同, 客户端发送 client_certificate 与 certificate_verify_message.
certificate_verify_message 是采用client的私钥加密以及协商的通信信息得到数据, 服务端采用对应的公钥解密并验证.
2.2.4.2. Client Key Exchange
客户端计算产生随机数 pre_master_secret, 并用证书公钥加密, 发送给服务端.
此时客户端已经获得计算协商密钥的全部信息:两个明文随机数 random_client 与 random_server, 以及自己计算产生的 pre_master_secret
计算得到协商密钥: session_secret = encrypt(random_client, random_server, pre_master_secret)
2.2.4.3. Change Cipher Spec
发送 change_cipher_spec 标识, 用于通知服务端后续的通信采用协商的通信密钥和加密算法进行.
2.2.4.4. Encrypt Handshake Message
客户端结合之前所有通信参数的 hash 值与其他相关信息生成一段数据, 采用协商密钥 session_secret 与算法进行加密, 然后发送给服务器用于数据与握手验证.
2.2.5. 服务端最后回应
服务端用证书私钥解密加密的 pre_master_secret, 并计算出 session_secret.
服务端计算之前所有接收信息的hash值, 然后解密客户端发送的 encrypt_handshake_message, 验证数据和密钥正确性.
2.2.5.1. Change Cipher Spec
服务端验证通过后, 统一发送 change_cipher_spec, 通知客户端后续的通信采用协商的通信密钥和加密算法进行.
2.2.5.2. Encrypt Handshake Message
服务端也结合之前所有通信参数的 hash 值与其他相关信息生成一段数据, 采用协商密钥 session_secret 与算法进行加密, 然后发送给客户端.
2.2.6. 握手结束
客户端同样计算并验证 encrypt_handshake_message, 验证通过则握手完成.
2.2.7. 加密通信
开始使用协商密钥和算法进行通信.
2.3. 密钥
2.3.1. 密钥计算
密钥计算流程如下:
- 客户端使用 RSA 或 DH 等加密算法生成 pre_master_secret
- pre_master_secret 结合 random_client 和 random_server 两个随机数通过 PseudeRandomFunction (PRF)计算得到 master_secret
- master_secret 结合 random_client 和 random_server 两个随机数通过迭代计算得到 Key-Material
2.3.2. 密钥使用
密钥经过12轮迭代计算会获得12个hash值, 分组成为6个元素, 列表如下:
- Client Mac Key
- Server Mac Key
- Client Encryption Key
- Server Encryption Key
- Client IV
- Server IV
其中, Mac Key 用于完整性效验, Encryption Key 用于对称加密, IV 作为加密算法的初始化向量.
用法如下:
- Mac Key, Encryption Key和IV是一组加密元素, 分别被客户端和服务端使用, 但是则两组元素都被两边同时获取.
- 客户端使用 client 组元素加密数据, 服务端使用 client 组元素解密; 服务端使用 server 组元素加密数据, 客户使用 server 组元素解密.
- 双向通信的不同方向使用的密钥不同, 破解通信至少需要破解2次.
- MAC 值的计算包括2个 Hash 值: Mac Key 和 Hash(编号, 包类型, 长度, 压缩数据)
2.4. 其他要点
-
pre_master_secret 前2个字节是TLS版本号
这是一个比较重要的用来核对握手数据的版本号.
因为在 Client Hello 阶段, 客户端会发送一份加密套件列表和定钱支持的 TLS/SSL 的版本号给服务端, 而且是使用明文传送的, 如果握手的数据包被破解后, 攻击者恒可能串改数据包, 选择一个安全性较低的加密太监和版本给服务端, 从而对数据进行破坏.
所以, 服务端需要对密文中解密出来的 pre_master_secret 版本号跟之前 Client Hello 阶段的版本号进行比对, 如果版本号变低, 则立即停止发送任何消息.
-
不管客户端还是服务端, 都需要随机数, 这样生成的密钥才不会每次都一样.
由于 TLS/SSL 协议中证书是静态的, 因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性.
对于 RSA 密钥交换算法来说, pre_master_secret 本身就是一个随机数, 再加上 hello 消息中的随机, 三个随机数通过一个密钥导出器最终导出一个对称密钥.
pre_master_secret 的存在在于 SSL 协议不信任每个主机都能产生完全随机的随机数, 如果随机数不随机, 那么 pre_master_secret 就有可能被猜出来, 那么仅适用 pre_master_secret 作为密钥就不合适了, 因此必须引入新的随机因素, 那么客户端和服务器加上 pre_master_secret 三个随机数一同生成的密钥就不容易被猜出了, 一个伪随机可能完全不随机, 可是三个伪随机就十分接近随机了, 每增加一个自由度, 随机性增加的可不是一.
-
对应用层数据进行分片成合适的block
为分片数据编号, 防止重放攻击
3. HTTPS 性能与优化
HTTPS的优点在于:
- 身份认证, 信息加密和完整性效验, 提高了通信安全性
- 未对 TCP 和 HTTP 协议做任何改动
HTTPS付出代价便是增加了性能损耗, 主要体现在:
-
增加延时
一次完整的握手至少需要两端来回2次通信, 即至少增加延时 2 * RTT; 即使利用会话缓存从而复用连接, 延时也至少增加 1 * RTT.
-
CPU资源消耗更多
非对称算法 RSA 解密能力是当前困扰HTTPS接入的主要难题.
3.1. HTTPS 接入优化
-
CDN接入
HTTPS 增加的延时主要是传输延时 RTT, RTT 的特点是节点越近延时越小, CDN 天然离用户最近, 因此选择使用 CDN 作为 HTTPS 接入的入口, 将能够极大减少接入延时.
CDN 节点通过和业务服务器维持长连接, 会话复用和链路质量优化等可控方法, 极大减少 HTTPS 带来的延时.
-
会话缓存
虽然前文提到 HTTPS 即使采用会话缓存也要至少1*RTT的延时, 但是至少延时已经减少为原来的一半, 明显的延时优化;
同时, 基于会话缓存建立的 HTTPS 连接不需要服务器使用 RSA 私钥解密获取 pre_master_secret 信息, 可以省去 CPU 的消耗.
如果业务访问连接集中, 缓存命中率高, 则HTTPS的接入能力讲明显提升.
当前 TRP 平台的缓存命中率高峰时期大于 30%, 10k/s 的接入资源实际可以承载13k/s 的接入, 收效非常可观.
-
硬件加速
为接入服务器安装专用的SSL硬件加速卡, 作用类似 GPU, 释放 CPU, 能够具有更高的 HTTPS 接入能力且不影响业务程序的.
测试某硬件加速卡单卡可以提供35k的解密能力, 相当于175核 CPU, 至少相当于7台24核的服务器, 考虑到接入服务器其它程序的开销, 一张硬件卡可以实现接近10台服务器的接入能力.
-
远程解密
本地接入消耗过多的 CPU 资源, 浪费了网卡和硬盘等资源, 考虑将最消耗 CPU 资源的 RSA 解密计算任务转移到其它服务器, 如此则可以充分发挥服务器的接入能力, 充分利用带宽与网卡资源.
远程解密服务器可以选择 CPU 负载较低的机器充当, 实现机器资源复用, 也可以是专门优化的高计算性能的服务器.
当前也是 CDN 用于大规模HTTPS接入的解决方案之一.
-
SPDY/HTTP2
前面的方法分别从减少传输延时和单机负载的方法提高 HTTPS 接入性能, 但是方法都基于不改变 HTTP 协议的基础上提出的优化方法, SPDY/HTTP2 利用 TLS/SSL 带来的优势, 通过修改协议的方法来提升 HTTPS 的性能, 提高下载速度等.
4. Resource