HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,是一个安全通讯通道,它基于HTTP开发用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来讲它是HTTP的安全版,是使用TLS/SSL加密的HTTP协议。nginx
HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具备身份验证、信息加密和完整性校验的功能,能够避免此类问题发生。算法
TLS/SSL全称安全传输层协议Transport Layer Security, 是介于TCP和HTTP之间的一层安全协议,不影响原有的TCP协议和HTTP协议,因此使用HTTPS基本上不须要对HTTP页面进行太多的改造。windows
HTTPS是在HTTP上创建SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。HTTPS主要做用是:浏览器
(1)对数据进行加密,并创建一个信息安全通道,来保证传输过程当中的数据安全;缓存
(2)对网站服务器进行真实身份认证。安全
HTTP是互联网上应用最为普遍的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议。HTTP是采用明文形式进行数据传输,极易被不法份子窃取和篡改。服务器
一、HTTPS是加密传输协议,HTTP是名文传输协议;cookie
二、 HTTPS标准端口443,HTTP标准端口80;网络
三、 HTTPS基于传输层,HTTP基于应用层;session
协议层面的区别以下图:
HTTPS协议的主要功能基本都依赖于TLS/SSL协议,TLS/SSL的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
常见的有 MD五、SHA一、SHA256,该类函数特色是函数单向不可逆、对输入很是敏感、输出长度固定,针对数据的任何修改都会改变散列函数的结果,用于防止信息篡改并验证数据的完整性;
在信息传输过程当中,散列函数不能单独实现信息防篡改,由于明文传输,中间人能够修改信息以后从新计算信息摘要,所以须要对传输的信息以及信息摘要进行加密;
常见的有 AES-CBC、DES、3DES、AES-GCM等,相同的密钥能够用于信息的加密和解密,掌握密钥才能获取信息,可以防止信息窃听,通讯方式是1对1;
对称加密的优点是信息传输1对1,须要共享相同的密码,密码的安全是保证信息安全的基础,服务器和 N 个客户端通讯,须要维持 N 个密码记录,且缺乏修改密码的机制;
即常见的 RSA 算法,还包括 ECC、DH 等算法,算法特色是,密钥成对出现,通常称为公钥(公开)和私钥(保密),公钥加密的信息只能私钥解开,私钥加密的信息只能公钥解开。所以掌握公钥的不一样客户端之间不能互相解密信息,只能和掌握私钥的服务器进行加密通讯,服务器能够实现1对多的通讯,客户端也能够用来验证掌握私钥的服务器身份。
非对称加密的特色是信息传输1对多,服务器只须要维持一个私钥就可以和多个客户端进行加密通讯,但服务器发出的信息可以被全部的客户端解密,且该算法的计算复杂,加密速度慢。
结合三类算法的特色,TLS的基本工做方式是,客户端使用非对称加密与服务器进行通讯,实现身份验证并协商对称加密使用的密钥,而后对称加密算法采用协商密钥对信息以及信息摘要进行加密通讯,不一样的节点之间采用的对称密钥不一样,从而能够保证信息只能通讯双方获取。
下图展示了----基于RSA握手和密钥交换的客户端验证服务器为示例详解TLS/SSL握手过程。
(1).client_hello
客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息,相关信息以下:
支持的最高TSL协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本再也不使用低于 TLSv1 的版本;
客户端支持的加密套件 cipher suites 列表, 每一个加密套件对应前面 TLS 原理中的四个功能的组合:认证算法 Au (身份验证)、密钥交换算法 KeyExchange(密钥协商)、对称加密算法 Enc (信息加密)和信息摘要 Mac(完整性校验);
支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
随机数 random_C,用于后续的密钥的生成;
扩展字段 extensions,支持协议与算法的相关参数以及其它辅助信息等,常见的 SNI 就属于扩展字段,后续单独讨论该字段做用。
(2).server_hello+server_certificate+sever_hello_done
(a) server_hello, 服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 等,其中随机数用于后续的密钥协商;
(b)server_certificates, 服务器端配置对应的证书链,用于身份验证与密钥交换;
(c) server_hello_done,通知客户端 server_hello 信息发送结束;
(3).证书校验
客户端验证证书的合法性,若是验证经过才会进行后续通讯,不然根据错误状况不一样作出提示和操做,合法性验证包括以下:
证书链的可信性 trusted certificate path,方法如前文所述;
证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不一样的客户端行为会不一样;
有效期 expiry date,证书是否在有效时间范围;
域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;
(4).client_key_exchange+change_cipher_spec+encrypted_handshake_message
(a) client_key_exchange,合法性验证经过以后,客户端计算产生随机数字 Pre-master,并用证书公钥加密,发送给服务器;
(b) 此时客户端已经获取所有的计算协商密钥须要的信息:两个明文随机数 random_C 和 random_S 与本身计算产生的 Pre-master,计算获得协商密钥;
enc_key=Fuc(random_C, random_S, Pre-Master)
(c) change_cipher_spec,客户端通知服务器后续的通讯都采用协商的通讯密钥和加密算法进行加密通讯;
(d) encrypted_handshake_message,结合以前全部通讯参数的 hash 值与其它相关信息生成一段数据,采用协商密钥 session secret 与算法进行加密,而后发送给服务器用于数据与握手验证;
(5).change_cipher_spec+encrypted_handshake_message
(a) 服务器用私钥解密加密的 Pre-master 数据,基于以前交换的两个明文随机数 random_C 和 random_S,计算获得协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
(b) 计算以前全部接收信息的 hash 值,而后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
(c) change_cipher_spec, 验证经过以后,服务器一样发送 change_cipher_spec 以告知客户端后续的通讯都采用协商的密钥与算法进行加密通讯;
(d) encrypted_handshake_message, 服务器也结合全部当前的通讯参数信息生成一段数据并采用协商密钥 session secret 与算法加密并发送到客户端;
(6).握手结束
客户端计算全部接收信息的 hash 值,并采用协商密钥解密 encrypted_handshake_message,验证服务器发送的数据和密钥,验证经过则握手完成;
(7).加密通讯
开始使用协商密钥与算法进行加密通讯。
注意:
(a) 服务器也能够要求验证客户端,即双向认证,能够在过程2要发送 client_certificate_request 信息,客户端在过程4中先发送 client_certificate与certificate_verify_message 信息,证书的验证方式基本相同,certificate_verify_message 是采用client的私钥加密的一段基于已经协商的通讯信息获得数据,服务器能够采用对应的公钥解密并验证;
(b) 根据使用的密钥交换算法的不一样,如 ECC 等,协商细节略有不一样,整体类似;
(c) sever key exchange 的做用是 server certificate 没有携带足够的信息时,发送给客户端以计算 pre-master,如基于 DH 的证书,公钥不被证书中包含,须要单独发送;
(d) change cipher spec 实际可用于通知对端改版当前使用的加密通讯方式,当前没有深刻解析;
(e) alter message 用于指明在握手或通讯过程当中的状态改变或错误信息,通常告警信息触发条件是链接关闭,收到不合法的信息,信息解密失败,用户取消操做等,收到告警信息以后,通讯会被断开或者由接收方决定是否断开链接。
为了加快创建握手的速度,减小协议带来的性能下降和资源消耗(具体分析在后文),TLS 协议有两类会话缓存机制:会话标识 session ID 与会话记录 session ticket。
session ID 由服务器端支持,协议中的标准字段,所以基本全部服务器都支持,服务器端保存会话ID以及协商的通讯信息,Nginx 中1M 内存约能够保存4000个 session ID 机器相关信息,占用服务器资源较多;
session ticket 须要服务器和客户端都支持,属于一个扩展字段,支持范围约60%(无可靠统计与来源),将协商的通讯信息加密以后发送给客户端保存,密钥只有服务器知道,占用服务器资源不多。
两者对比,主要是保存协商信息的位置与方式不一样,相似与 http 中的 session 与 cookie。
两者都存在的状况下,(nginx 实现)优先使用 session_ticket。
握手过程以下图:
注意:虽然握手过程有1.5个来回,可是最后客户端向服务器发送的第一条应用数据不须要等待服务器返回的信息,所以握手延时是1*RTT。
(1).会话标识 session ID
(a) 若是客户端和服务器之间曾经创建了链接,服务器会在握手成功后返回 session ID,并保存对应的通讯参数在服务器中;
(b) 若是客户端再次须要和该服务器创建链接,则在 client_hello 中 session ID 中携带记录的信息,发送给服务器;
(c) 服务器根据收到的 session ID 检索缓存记录,若是没有检索到货缓存过时,则按照正常的握手过程进行;
(d) 若是检索到对应的缓存记录,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息做用相似,encrypted_handshake_message 是到当前的通讯参数与 master_secret的hash 值;
(f) 若是客户端可以验证经过服务器加密数据,则客户端一样发送 change_cipher_spec 与 encrypted_handshake_message 信息;
(g) 服务器验证数据经过,则握手创建成功,开始进行正常的加密数据通讯。
(2).会话记录 session ticket
(a) 若是客户端和服务器之间曾经创建了链接,服务器会在 new_session_ticket 数据中携带加密的 session_ticket 信息,客户端保存;
(b) 若是客户端再次须要和该服务器创建链接,则在 client_hello 中扩展字段 session_ticket 中携带加密信息,一块儿发送给服务器;
(c) 服务器解密 sesssion_ticket 数据,若是可以解密失败,则按照正常的握手过程进行;
(d) 若是解密成功,则返回 change_cipher_spec 与 encrypted_handshake_message 信息,两个信息做用与 session ID 中相似;
(f)若是客户端可以验证经过服务器加密数据,则客户端一样发送 change_cipher_spec与encrypted_handshake_message 信息;
(g) 服务器验证数据经过,则握手创建成功,开始进行正常的加密数据通讯。
重建链接 renegotiation 即放弃正在使用的 TLS 链接,重新进行身份认证和密钥协商的过程,特色是不须要断开当前的数据传输就能够从新身份认证、更新密钥或算法,所以服务器端存储和缓存的信息均可以保持。客户端和服务器都可以发起重建链接的过程,当前 windows 2000 & XP 与 SSL 2.0不支持。
(1).服务器重建链接
服务器端重建链接通常状况是客户端访问受保护的数据时发生。基本过程以下:
(a) 客户端和服务器之间创建了有效 TLS 链接并通讯;
(b) 客户端访问受保护的信息;
(c) 服务器端返回 hello_request 信息;
(d) 客户端收到 hello_request 信息以后发送 client_hello 信息,开始从新创建链接。
(2).客户端重建链接
客户端重建链接通常是为了更新通讯密钥。
(a) 客户端和服务器之间创建了有效 TLS 链接并通讯;
(b) 客户端须要更新密钥,主动发出 client_hello 信息;
(c) 服务器端收到 client_hello 信息以后没法当即识别出该信息非应用数据,所以会提交给下一步处理,处理完以后会返回通知该信息为要求重建链接;
(d) 在肯定重建链接以前,服务器不会当即中止向客户端发送数据,可能刚好同时或有缓存数据须要发送给客户端,可是客户端不会再发送任何信息给服务器;
(e) 服务器识别出重建链接请求以后,发送 server_hello 信息至客户端;
(f) 客户端也一样没法当即判断出该信息非应用数据,一样提交给下一步处理,处理以后会返回通知该信息为要求重建链接;
(g) 客户端和服务器开始新的重建链接的过程。
上节提到了两个明文传输的随机数 random_C 和 random_S 与经过加密在服务器和客户端之间交换的 Pre-master,三个参数做为密钥协商的基础。本节讨论说明密钥协商的基本计算过程以及通讯过程当中的密钥使用。
(1).计算 Key
涉及参数 random client 和 random server, Pre-master, Master secret, key material, 计算密钥时,服务器和客户端都具备这些基本信息,交换方式在上节中有说明,计算流程以下:
(a) 客户端采用 RSA 或 Diffie-Hellman 等加密算法生成 Pre-master;
(b) Pre-master 结合 random client 和 random server 两个随机数经过 PseudoRandomFunction(PRF)计算获得 Master secret;
(c) Master secret 结合 random client 和 random server 两个随机数经过迭代计算获得 Key material;
如下为一些重要的记录,能够解决部分爱深刻研究朋友的疑惑,copy的材料,分享给你们:
(a) PreMaster secret 前两个字节是 TLS 的版本号,这是一个比较重要的用来核对握手数据的版本号,由于在 Client Hello 阶段,客户端会发送一份加密套件列表和当前支持的 SSL/TLS 的版本号给服务端,并且是使用明文传送的,若是握手的数据包被破解以后,攻击者颇有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。因此,服务端须要对密文中解密出来对的 PreMaster 版本号跟以前 Client Hello 阶段的版本号进行对比,若是版本号变低,则说明被串改,则当即中止发送任何消息。(copy)
(b) 无论是客户端仍是服务器,都须要随机数,这样生成的密钥才不会每次都同样。因为 SSL 协议中证书是静态的,所以十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于 RSA 密钥交换算法来讲,pre-master-key 自己就是一个随机数,再加上 hello 消息中的随机,三个随机数经过一个密钥导出器最终导出一个对称密钥。
pre master 的存在在于 SSL 协议不信任每一个主机都能产生彻底随机的随机数,若是随机数不随机,那么 pre master secret 就有可能被猜出来,那么仅适用 pre master secret 做为密钥就不合适了,所以必须引入新的随机因素,那么客户端和服务器加上 pre master secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能彻底不随机,但是三个伪随机就十分接近随机了,每增长一个自由度,随机性增长的可不是一。
(2).密钥使用
Key 通过12轮迭代计算会获取到12个 hash 值,分组成为6个元素,列表以下:
(a) mac key、encryption key 和 IV 是一组加密元素,分别被客户端和服务器使用,可是这两组元素都被两边同时获取;
(b) 客户端使用 client 组元素加密数据,服务器使用 client 元素解密;服务器使用 server 元素加密,client 使用 server 元素解密;
(c) 双向通讯的不一样方向使用的密钥不一样,破解通讯至少须要破解两次;
(d) encryption key 用于对称加密数据;
(e) IV 做为不少加密算法的初始化向量使用,具体能够研究对称加密算法;
(f) Mac key 用于数据的完整性校验;
(3).数据加密通讯过程
(a) 对应用层数据进行分片成合适的 block;
(b) 为分片数据编号,防止重放攻击;
(c) 使用协商的压缩算法压缩数据;
(d) 计算 MAC 值和压缩数据组成传输数据;
(e) 使用 client encryption key 加密数据,发送给服务器 server;
(f) server 收到数据以后使用 client encrytion key 解密,校验数据,解压缩数据,从新组装。
注:MAC值的计算包括两个 Hash 值:client Mac key 和 Hash (编号、包类型、长度、压缩数据)。
关于抓包再也不详细分析,按照前面的分析,基本的状况都可以匹配,根据日常定位问题的过程,我的提些认为须要注意的地方:
(1).抓包 HTTP 通讯,可以清晰的看到通讯的头部和信息的明文,可是 HTTPS 是加密通讯,没法看到 HTTP 协议的相关头部和数据的明文信息,
(2).抓包 HTTPS 通讯主要包括三个过程:TCP 创建链接、TLS 握手、TLS 加密通讯,主要分析 HTTPS 通讯的握手创建和状态等信息。
(3).client_hello
根据 version 信息可以知道客户端支持的最高的协议版本号,若是是 SSL 3.0 或 TLS 1.0 等低版本协议,很是注意可能由于版本低引发一些握手失败的状况;
根据 extension 字段中的 server_name 字段判断是否支持SNI,存在则支持,不然不支持,对于定位握手失败或证书返回错误很是有用;
会话标识 session ID 是标准协议部分,若是没有创建过链接则对应值为空,不为空则说明以前创建过对应的链接并缓存;
会话记录 session ticke t是扩展协议部分,存在该字段说明协议支持 sesssion ticket,不然不支持,存在且值为空,说明以前未创建并缓存链接,存在且值不为空,说明有缓存链接。
(4).server_hello
根据 TLS version 字段可以推测出服务器支持的协议的最高版本,版本不一样可能形成握手失败;
基于 cipher_suite 信息判断出服务器优先支持的加密协议;
(5).ceritficate
服务器配置并返回的证书链,根据证书信息并于服务器配置文件对比,判断请求与指望是否一致,若是不一致,是否返回的默认证书。
(6).alert
告警信息 alert 会说明创建链接失败的缘由即告警类型,对于定位问题很是重要。
前文讨论了HTTPS原理与优点:身份验证、信息加密与完整性校验等,且未对TCP和HTTP协议作任何修改。但经过增长新协议以实现更安全的通讯必然须要付出代价,HTTPS协议的性能损耗主要体现以下:
(1).增长延时
分析前面的握手过程,一次完整的握手至少须要两端依次来回两次通讯,至少增长延时2* RTT,利用会话缓存从而复用链接,延时也至少1* RTT*。
(2).消耗较多的CPU资源
除数据传输以外,HTTPS通讯主要包括对对称加解密、非对称加解密(服务器主要采用私钥解密数据);压测 TS8 机型的单核 CPU:对称加密算法AES-CBC-256 吞吐量 600Mbps,非对称 RSA 私钥解密200次/s。不考虑其它软件层面的开销,10G 网卡为对称加密须要消耗 CPU 约17核,24核CPU最多接入 HTTPS 链接 4800;
静态节点当前10G 网卡的 TS8 机型的 HTTP 单机接入能力约为10w/s,若是将全部的HTTP链接变为HTTPS链接,则明显RSA的解密最早成为瓶颈。所以,RSA的解密能力是当前困扰HTTPS接入的主要难题。
(1).CDN接入
HTTPS 增长的延时主要是传输延时 RTT,RTT 的特色是节点越近延时越小,CDN 自然离用户最近,所以选择使用 CDN 做为 HTTPS 接入的入口,将可以极大减小接入延时。CDN 节点经过和业务服务器维持长链接、会话复用和链路质量优化等可控方法,极大减小 HTTPS 带来的延时。
(2).会话缓存
虽然前文提到 HTTPS 即便采用会话缓存也要至少1*RTT的延时,可是至少延时已经减小为原来的一半,明显的延时优化;同时,基于会话缓存创建的 HTTPS 链接不须要服务器使用RSA私钥解密获取 Pre-master 信息,能够省去CPU 的消耗。若是业务访问链接集中,缓存命中率高,则HTTPS的接入能力讲明显提高。当前TRP平台的缓存命中率高峰时期大于30%,10k/s的接入资源实际能够承载13k/的接入,收效很是可观。
(3).硬件加速
为接入服务器安装专用的SSL硬件加速卡,做用相似 GPU,释放 CPU,可以具备更高的 HTTPS 接入能力且不影响业务程序的。测试某硬件加速卡单卡能够提供35k的解密能力,至关于175核 CPU,至少至关于7台24核的服务器,考虑到接入服务器其它程序的开销,一张硬件卡能够实现接近10台服务器的接入能力。
(4).远程解密
本地接入消耗过多的 CPU 资源,浪费了网卡和硬盘等资源,考虑将最消耗 CPU 资源的RSA解密计算任务转移到其它服务器,如此则能够充分发挥服务器的接入能力,充分利用带宽与网卡资源。远程解密服务器能够选择 CPU 负载较低的机器充当,实现机器资源复用,也能够是专门优化的高计算性能的服务器。当前也是 CDN 用于大规模HTTPS接入的解决方案之一。