1.HTTPS是什么
使用来自wiki的解释:
超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。这个协议由网景公司(Netscape)在1994年首次提出,随后扩展到互联网上。
历史上,HTTPS连接经常用于万维网上的交易支付和企业信息系统中敏感信息的传输。在2000年代末至2010年代初,HTTPS开始广泛使用,以确保各类型的网页真实,保护账户和保持用户通信,身份和网络浏览的私密性。
另外,还有一种安全超文本传输协议(S-HTTP)的HTTP安全传输实现,但是HTTPS的广泛应用而成为事实上的HTTP安全传输实现,S-HTTP并没有得到广泛支持。
ps:翻阅资料发现,S-HTTP的原理是对于每次数据的交互都进行 RSA非对称加密,对比HTTPS来说,S-HTTP加密单次事务的交互,而HTTPS则是对通信层进行加密,我想效率和普适性可能也是决定市场采用HTTPS而不是S-HTTP的一大因素。
1.1 TLS/SSL
1.1.1 介绍
传输层安全性协议(英语:Transport Layer Security,缩写:TLS)及其前身安全套接层(英语:Secure Sockets Layer,缩写:SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。网景公司(Netscape)在1994年推出首版网页浏览器-网景导航者时,推出HTTPS协议,以SSL进行加密,这是SSL的起源。IETF将SSL进行标准化,1999年公布TLS 1.0标准文件(RFC 2246)。随后又公布TLS 1.1(RFC 4346,2006年)、TLS 1.2(RFC 5246,2008年)和TLS 1.3(RFC 8446,2018年)。在浏览器、电子邮件、即时通信、VoIP、网络传真等应用程序中,广泛使用这个协议。许多网站,如Google、Facebook、Wikipedia等也以这个协议来创建安全连线,发送资料。目前已成为互联网上保密通信的工业标准。
SSL包含记录层(Record Layer)和传输层,记录层协议确定传输层数据的封装格式。传输层安全协议使用X.509认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密钥作为会谈密钥(Session key)。这个会谈密钥是用来将通信两方交换的资料做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。
1.1.2 数字证书
是用于公开密钥基础建设的电子文件,用来证明公开密钥拥有者的身份。此文件包含了公钥信息、拥有者身份信息(主体)、以及数字证书认证机构(发行者)对这份文件的数字签名,以保证这个文件的整体内容正确无误。拥有者凭着此文件,可向电脑系统或其他用户表明身份,从而对方获得信任并授权访问或使用某些敏感的电脑服务。电脑系统或其他用户可以透过一定的程序核实证书上的内容,包括证书有否过期、数字签名是否有效,如果你信任签发的机构,就可以信任证书上的密钥,凭公钥加密与拥有者进行可靠的通信。
简而言之,认证机构用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。
人们透过信任数字证书认证机构的根证书、及其使用公开密钥加密作数字签名核发的公开密钥认证,形成信任链架构,已在TLS实现并在万维网的HTTPS、在电子邮件的SMTPS和STARTTLS广泛应用。业界现行的标准是国际电信联盟电信标准化部门制定的X.509[2],并由IETF发行的RFC 5280详细述明。
1.1.3 x.509
X.509是密码学里公钥证书的格式标准。X.509证书已应用在包括TLS/SSL在内的众多网络协议里,同时它也用在很多非在线应用场景里,比如电子签名服务。X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。对于一份经由可信的证书签发机构签名或者可以通过其它方式验证的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,对文档进行数字签名。
除了证书本身功能,X.509还附带了证书吊销列表和用于从最终对证书进行签名的证书签发机构直到最终可信点为止的证书合法性验证算法。
X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。
1.2 加密相关
1.2.1 Hash
Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
Hash算法也被称为散列算法,Hash算法虽然被称为算法,但实际上它更像是一种思想。Hash算法没有一个固定的公式,只要符合散列思想的算法都可以被称为是Hash算法。
特点: 无法反向破解,可以用来校验唯一性.
1.2.2 对称加密
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密
常见: AES DES 3DES 特点:效率高
1.2.3 非对称加密
一对密钥,公钥和私钥,公钥加密的数据只能通过私钥来解密,私钥加密的数据只能通过公钥解密. 保证非对称加密的安全性是极大整数的因数分解(数学实现基于互质,欧拉函数,欧拉定理,模反,具体不详细解释),wiki是这么说的:
对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。
假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。
只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。
常见: RSA 特点:效率低,耗时长
1.3 为什么要引入HTTPS
使用http交互信息存在以下隐患:
通信使用明文(不加密),内容会被窃听
不验证通信方的的身份,因此有可能遭遇伪装
无法验证报文的完整性,所以可能被篡改
1.4 总结
个人来看,由于HTTP的不安全性,急需一个安全的协议做补充,而HTTPS就是在HTTP协议的基础上,添加了传输层安全性协议(TLS/SSL),TLS/SSL是一个协议标准,而x.509则是这个协议标准的一个实现.而x.509就用到了加密相关的hash算法,对称加密算法,非对称加密算法.
2.HTTPS的执行流程
1.ClientHello 首先https请求是基于http的,也就是基于tcp的,所以先得建立tcp三次握手,这个就不说了,然后tcp握手后是SSL层的握手,也就是图中的ClientHello消息,client发送本地最新的TLS版本、算法组合的一个集合和其他很多辅助的信息,并且生成一个随机数A。具体的内容可以看下图:
可以看到随机数(Random
)是一个GMT UNIX时间加上一串随机字节,算法组合(Cipher Suite
)有26种。
2.ServerHello Server收到这些信息后比对自己的TLS版本,选择其中低的一个作为返回,并且从算法组合的集合中选出一种合适的组合,然后同样也生成一个随机数B,一起打包到ServerHello中传回给Client。内容如图:
这里选出了一种CipherSuite算法组合。
3.Certificatie,ServerHelloDone 服务端在选出沟通策略之后将自己的证书信息告诉Client端(Certificate
),通知Client关于秘钥更新的信息(ServerkeyExchange
),接下去就看你的了,并且表示该发的都发给你了,我的Hello结束了(ServerHelloDone
)。
4.Client收到2,3步的信息后先验证证书是不是合法的,包括它的颁发机构,域名匹配,有限期限等,这个具体的过程就不探究了,只要知道这些步骤就行了。
5.证书验证通过之后,生成随机数C1,然后用证书内容中的公钥通过服务器选择的非对称加密算法加密,得出为C2。
6.由之前的三个随机数A、B、C1通过一个伪随机函数再生成一个D,注意!这个是最终http真正使用的加密秘钥!!!。
7.由D再次通过伪随机函数生成一个秘钥组,包含6个秘钥,假设为P1,P2,P3,P4,P5,P6。
8.ClientKeyExchange。通知Server秘钥相关的信息,发送第5步中算出的C2给Server端。
9.Client端发送ClientKeyExchange之后,计算之前所有与Server端交互消息的hash值,假设为client_hash1,用步骤7中得到的其中一个P1进行加密,结果为E。
10.Server端收到C2后用私钥结合非对称算法解密C2,得到C1。
11.同样的Server端也根据A、B、C1由伪随机函数生成D(最终的加密秘钥!!!),再由D得出秘组钥(P1-P6),因为这里涉及到的算法都是一样的,所以得出的秘钥也是一样的。
12.Server端计算之前所有和Client端交互消息的hash值,假设为server_hash2,大家可能发现了,11、12跟Client端的6、7、9过程一致,只是少了9中的P1加密过程。
13.这个时候Client端会发送ChangeCipherSpec消息和EncryptedHandshakeMessage消息,通知Server端接下去使用选定的加密策略来通信了,并且将第9步中的E传给了Server。(这里几个步骤的顺序只是为了好理解一点而这样排列,实际两条线是独立在处理信息的,所以先后顺序不能保证)
14.这个时候Client会再次计算之前握手消息的hash值,得出结果client_hash2。
15.Server在收到EncryptedHandshakeMessage消息带过来的E之后,利用步骤11中的P1解密E,由于加密算法和P1都是相同的,所以这里还原出了client_hash1,然后与步骤12中的server_hash2比对,如果一样说明之前的几条协商秘钥的消息都被对方正确无误的理解了。
16.Server端再次对之前的消息做hash值,得出server_hash2,用P2进行加密结果为F,然后通过ChangeCipherSpec-EncryptedHandshakeMessage消息传给Client端。
17.Client收到Server的消息后根据P2解密F还原得出server_hash2,与client_hash2比对如果一致,则认为之前的交互过程都是正确无误且被对方理解的。至此,整个握手过程就结束了,之后的http数据报就会被之前确定的加密策略和加密秘钥D进行加密传输了。
总结:其实最终我们发现整个握手过程中并没有直接传输最终的加密秘钥D,而且交换了一些算法策略和生成D的一些参数,这样相对来说会更安全一点,直接传D的话这个过程就由Client端完成了,中间如果出什么差错Server会无感知无条件的信任Client传过来的D,就有可能出现问题了,所以采用只传策略和参数,并且由双方共同参与,这样安全性和正确性就会提高很多。贴一张整个过程的抓包图:
3.HTTPS的一些细节
1.HTTPS过程中为什么要使用随机数?
主要是为了防止重放攻击(回放攻击),重放攻击是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。
2.HTTPS必须在每次请求中都要先在SSL层进行握手?
浏览器客户端访问同一个https服务器,可以不必每次都进行完整的TLS Handshake,因为完整的TLS Handshake,涉及到认证服务器的身份(数字证书),需要做大量的非对称加密/解密运算,此外还需要做伪随机函数PRF,通过“Pre-Master Key”、“Server Nonce”、“Client Nonce”共同推导出session key,非对称加密算法RSA/DSA非常耗费CPU资源。
为了克服这个困难,服务器维护一个以session ID为索引的结构体,用于临时存放session key,并在TLS handshake 阶段分享给浏览器。
当浏览器重新连接https 服务器时,TLS handshake 阶段,出示自己的session ID,服务器获得session ID,以此为索引,可以获得和该浏览器共同拥有的session key,使用session key可以直接对用户流量做加密/解密动作。
这样避免了大量的幂、指数计算。
当然,如果服务器没有查找到session ID,双方的TLS安全参数协商按照正常流程走。
使用 charles 抓包进行分析 Session ID 的使用情况。假设有一次请求,服务端允许使用 Session ID,那么会有下面的流程:
客户端的 Client Hello 带上 Session ID
服务端复用 Session ID 后,会直接略过协商加密密钥的过程,直接发出一个 Change Cipher Spec 报文
-
然后就是加密的握手信息报文
3.为什么我用Charles抓包可以看到HTTPS的内容
1.客户端向服务器发起HTTPS请求
2.Charles拦截客户端的请求,伪装成客户端向服务器进行请求
3.服务器向“客户端”(实际上是Charles)返回服务器的CA证书
4.Charles拦截服务器的响应,获取服务器证书公钥,然后自己制作一张证书,将服务器证书替换后发送给客户端。(这一步,Charles拿到了服务器证书的公钥)
5.客户端接收到“服务器”(实际上是Charles)的证书后,生成一个对称密钥,用Charles的公钥加密,发送给“服务器”(Charles)
6.Charles拦截客户端的响应,用自己的私钥解密对称密钥,然后用服务器证书公钥加密,发送给服务器。(这一步,Charles拿到了对称密钥
7.服务器用自己的私钥解密对称密钥,向“客户端”(Charles)发送响应
8.Charles拦截服务器的响应,替换成自己的证书后发送给客户端
至此,连接建立,Charles拿到了 服务器证书的公钥 和 客户端与服务器协商的对称密钥,之后就可以解密或者修改加密的报文了。
(核心点:Charles生成了自己一套公钥,私钥,和自己的证书,因为自己的证书无法通过校验,所以需要客户端主动授权,客户端授权后,charles就可以完全代替客户端与服务端交互,与服务端交互用的是服务端的公钥加密,与客户端交互用的是charles自己的私钥解密)