tlsv1.2基于tls协议的怎么解密

  随着近些年网络安全事情的頻繁发生使得用户对网络通信安全的意识越来越强。国内外的网络服务提供商都逐渐提供全站的安全通信服务如国内的淘宝、百度先後宣布已经完成了全站部署https。微信现有的安全通信基于tls协议的是基于用户登录的时候派发的SessionKey对应用数据进行加密的该基于tls协议的在工程實现上,已经过多次迭代优化但是仍然有一些缺点:

  1. 原有的加密通信基于tls协议的是存在于业务层的。加密保护的是请求包包体部分但昰包头部分是明文,包头包含用户id和请求的业务id等信息这主要是为了在proxy做路由所需要的。这样会存在数据被截获后建立映射关联分析的風险   

  2. 原有的加密通信基于tls协议的使用的密码学基于tls协议的和算法与业界最新成果有差距,安全强度有待加强   

  鉴于上述原洇,微信需要一套能够加密保护Client到Server之间所有网络通信数据、且加密通信保护必须对业务开发人员透明的安全通信基于tls协议的由此诞生了mmtls。

  考虑到系统安全性与可用性和性能等指标之间可能存在相互影响某种程度上,安全性与这些指标是负相关的因此在设计的时候對mmtls提出了以下要求: 

  1. 安全性。主要体现在防窃听防篡改,防重放防伪造。 

  2. 低延迟、低资源消耗要保证数据在传输过程中不会增加明显的延迟;后台负载增加在可接受范围。  

  3. 可用性在一些极端情况下(如server负载过高),后台能够控制提供降级服务但是要注意鈈能被攻击者利用,进行降级攻击

  4. 可扩展性。基于tls协议的要可扩展、可升级方便添加安全强度更高的密码学组件,方便禁止过时的密碼学组件

  通过分析一些业界公开的安全通信基于tls协议的发现,它们都不能完全满足我们的要求例如TLS1.2中每次建立一个安全连接都需偠额外的2~1个RTT(全握手需要2-RTT),对于微信这么一个需要频繁网络通信的IM软件来说这对用户体验的伤害是极大的,尤其是在大量短连接存在嘚情况下额外的RTT对用户延迟的影响是相当明显的。

在TLS1.3草案标准中提出了0-RTT(不额外增加网络延时)建立安全连接的方法另外TLS基于tls协议的夲身通过版本号、CipherSuite、Extension机制提供了良好的可扩展性。但是TLS1.3草案标准仍然在制定过程中,基于标准的实现更是遥遥无期并且TLS1.3是一个对所有軟件制定的一个通用基于tls协议的,如果结合微信自己的特点还有很大的优化空间。因此我们最终选择基于TLS1.3草案标准设计实现我们自己嘚安全通信基于tls协议的mmtls。

  业务层数据加上mmtls之后由mmtls提供安全性,保护业务数据这类似于http加上tls后,变成https由tls保护http数据。mmtls处于业务层和原有的网络连接层之间不影响原有的网络策略。对于微信来说这里的网络连接层就是微信长连接(私有基于tls协议的)和微信短连接(http基於tls协议的)都是基于TCP的。

  图1描述的是把mmtls看成一个整体它所处的位置。进入mmtls内部它包含三个子基于tls协议的:Record基于tls协议的、Handshake基于tls协議的、Alert基于tls协议的。这其实是和TLS类似的它们之间的关系如下图: 

Protocol)也是record基于tls协议的的上层基于tls协议的,在Record基于tls协议的包中有一个字段鼡来区分当前这个Record数据包的上层基于tls协议的是Handshake、Alert还是业务基于tls协议的数据包。Handshake基于tls协议的用于完成Client与Server的握手协商协商出一个对称加密密鑰Key以及其他密码材料,用于后续数据加密Alert基于tls协议的用于通知对端发生错误,希望对端关闭连接目前mmtls为了避免server存在过多TCP

  说明:在丅文中,会出现多个对称密钥和多个非对称密钥对在本文中我会给有些密钥取一个专有的名字,以方便理解避免混淆如:pre_master_key,pre_shared_keycli_pub_key,cli_pri_key 等凡昰类似xxx_pub_key、xxx_pri_key这种名字的都是一对非对称公私钥,sign_keyverify_key是一对签名/验签的密钥其他的以key结尾的xxx_key都是对称密钥。

  Handshake基于tls协议的其实做的最主要嘚事情就是完成加密密钥的协商即让通信双方安全地获得一致的对称密钥,以进行加密数据传输在此基础上,还完成了一些优化工作如复用session以减少握手时间。

  在这里说明一下为什么mmtls以及TLS基于tls协议的需要一个Handshake子基于tls协议的和Record子基于tls协议的?其实“认证密钥协商+对稱加密传输”这种混合加密结构是绝大多数加密通信基于tls协议的的通用结构,在mmtls/TLS中Handshake子基于tls协议的负责密钥协商 Record子基于tls协议的负责数据對称加密传输。造成这种混合加密结构的本质原因还是因为单独使用公钥加密组件或对称加密组件都有不可避免的缺点公钥加密组件计算效率往往远低于对称加密组件,直接使用公钥加密组件加密业务数据这样的性能损耗任何Server都是无法承受的。

而如果单独使用对称加密組件进行网络加密通信在Internet这种不安全的信道下,这个对称加密密钥如何获取往往是一个难以解决的问题因此结合两类密码组件的优势,产生了“认证密钥协商+对称加密传输”这种混合加密结构另外,mmtls/TLS这种安全性和扩展性都很强的安全通信基于tls协议的在解决实际安全通信问题的时候,会有非常多的细节问题因此分离出两个子基于tls协议的来隔离复杂性。

  3.2.1 带认证的密钥协商

0-RTT PSK)并做了一些优化,后媔会详细分析如何产生这种决策的

  首先看一个,会遭受到攻击的密钥协商过程通信双方Alice和Bob使用ECDH密钥交换基于tls协议的进行密钥协商,ECDH密钥交换基于tls协议的拥有两个算法:

  • 密钥协商算法ECDH_compute_key以对方的公钥和自己的私钥作为输入,计算出一个密钥KeyECDH_compute_key算法使得通信双方计算出嘚密钥Key是一致的。

  这样一来Alice和Bob仅仅通过交换自己的公钥ECDH_pub_key就可以在Internet这种公开信道上共享一个相同密钥Key,然后用这个Key作为对称加密算法嘚密钥进行加密通信。 

  但是这种密钥协商算法仍然存在一个问题当Bob将他的Bob_ECDH_pub_key发送给Alice时,攻击者可以截获Bob_ECDH_pub_key自己运行ECDH_Generate_Key算法产生一个公鑰/私钥对,然后把他产生的公钥发送给Alice同理,攻击者可以截获Alice发送给Bob的Alice_ECDH_pub_key再运行ECDH_Generate_Key算法产生一个公钥/私钥对,并把这个公钥发送给BobAlice和Bob仍嘫可以执行基于tls协议的,产生一个密钥Key但实际上,Alice产生的密钥Key实际上是和攻击者Eve协商的;Bob产生的密钥Key也是和攻击者协商Eve的这种攻击方法被称为中间人攻击(Man

  那么,有什么解决办法中间人攻击呢产生中间人攻击的本质原因是协商过程中的数据没有经过端点认证,通信两端不知道收到的协商数据是来自对端还是来自中间人因此单纯的“密钥协商”是不够的,还需要“带认证的密钥协商”对数据进荇认证其实有对称和非对称的两种方式:基于消息认证码(Message Authentication Code)的对称认证和基于签名算法的非对称认证。消息认证码的认证方式需要一个私密的Key由于此时没有一个私密的Key,因此ECDH认证密钥协商就是ECDH密钥协商加上数字签名算法在mmtls中我们采用的数字签名算法为ECDSA。

   双方密鑰协商时再分别运行签名算法对自己发出的公钥ECDH_pub_key进行签名。收到信息后首先验证签名,如果签名正确则继续进行密钥协商。注意到由于签名算法中的公钥ECDSA_verify_key是一直公开的,攻击者没有办法阻止别人获取公钥除非完全掐断发送方的通信。这样一来中间人攻击就不存茬了,因为Eve无法伪造签名具体过程如图5所示:  

  事实上,在实际通信过程中只需要通信中某一方签名它的协商数据就可以保证不被Φ间人攻击,mmtls就是只对Server做认证不对Client做认证,因为微信客户端发布出去后任何人都可以获得,只要能够保证客户端程序本身的完整性僦相当于保证了客户端程序是由官方发布的,为认证合法的客户端而客户端程序本身的完整性不是mmtls基于tls协议的保护的范畴。

在这一点上TLS要复杂一些,TLS作为一个通用的安全通信基于tls协议的可能会存在一些需要对Client进行认证的场合,因此TLS提供了可选的双方相互认证的能力通过握手协商过程中选择的CipherSuite是什么类型来决定是否要对Server进行认证,通过Server是否发送CertificateRequest握手消息来决定是否要对Client进行认证由于mmtls不需要对Client做认证,在这块内容上比TLS简洁许多更加轻量级。

  PSK是在一次ECDH握手中由server下发的内容它的大致数据结构为PSK{key,ticket{key}}即PSK包含一个用来做对称加密密钥嘚key明文,以及用ticket_keykey进行加密的密文ticket当然PSK是在安全信道中下发的,也就是说在网络中进行传输的时候PSK是加密的中间人是拿不到key的。其中ticket_key呮有server才知道由server负责私密保存。

  PSK协商比较简单Client将PSK的ticket{key}部分发送给Server,由于只有Server才知道ticket_key因此key是不会被窃听的。Server拿到ticket后使用ticket_key解密得到key,嘫后Server用基于协商得到的密钥key对协商数据计算消息认证码来认证,这样就完成了PSK认证密钥协商PSK认证密钥协商使用的都是对称算法,性能仩比ECDH认证密钥协商要好很多 

  上述的两种认证密钥协商方式(1-RTT ECDHE, 1-RTT PSK)都需要一个额外RTT去获取对称加密key,在这个协商的RTT中是不带有业务数据嘚全部都是协商数据。那么是否存在一种密钥协商方式是在握手协商的过程中就安全地将业务数据传递给对端呢答案是有的,TLS1.3草案中提到了0-RTT密钥协商的方法

  0-RTT 握手想要达到的目标是在握手的过程中,捎带业务数据到对端这里难点是如何在客户端发起协商请求的时候就生成一个可信的对称密钥加密业务数据。在1-RTT ECDHE中Client生成一对公私钥(cli_pub_key,

Secret),然后用SS加密第一个业务数据包(实际上是通过SS衍生的密钥对业务数據进行加密后面详述),这样将SS加密的业务数据包和cli_pub_key一起传给ServerServer通过cli_pub_keystatic_server_private_key算出SS,解密业务数据包这样就达到了0-RTT密钥协商的效果。 

  这裏说明一下:ECDH协商中如果公私钥对都是临时生成的,一般称为ECDHE因此1-RTT的ECDH协商方式被称为1-RTT ECDHE握手,0-RTT 中有一个静态内置的公钥因此称为0-RTT ECDH握手。

  0-RTT PSK握手比较简单回顾1-RTT PSK握手,其实在进行1-RTT PSK握手之前Client已经有一个对称加密密钥key了,就直接拿这个对称加密密钥key加密业务数据然后将其和握手协商数据ticket{key}一起传递给Server就可以了。

  3.提高0-RTT密钥协商的安全性

  PFS(perfect forward secrecy)中文可叫做完全前向保密。它要求一个密钥被破解并不影响其他密钥的安全性,反映的密钥协商过程中大致的意思是用来产生会话密钥的长期密钥泄露出去,不会造成之前通信时使用的会话密钥的泄露;或者密钥协商方案中不存在长期密钥所有协商材料都是临时生成的。

  上面所述的0-RTT ECDH密钥协商加密的数据的安全性依赖于長期保存的密钥static_svr_pri_key如果static_svr_pri_key泄露,那么所有基于0-RTT ECDH协商的密钥SS都将被轻松计算出来它所加密的数据也没有任何保密性可言,为了提高前向安全性我们在进行0-RTT Secret)对业务数据进行保护的。这样即使static_svr_pri_key泄露也只有连接的第一个业务数据包能够被解密,提高前向安全性

  同样的,0-RTT PSK密鑰协商加密的数据的安全性依赖于长期保存密钥ticket_key如果ticket_key泄露,那么所有基于ticket_key进行保护的数据都将失去保密性因此同样可以在0-RTT PSK密钥协商的過程中,同时完成ECDHE密钥协商提高前向安全性。

  3.2.2 密钥协商需要关注的细节

  根据前面的描述可以知道要使得密钥协商过程不被中間人攻击,就必须要对协商数据进行认证下面拿1-RTT ECDHE握手方式来说明在进行认证过程中需要注意的细节。在1-RTT ECDHE中的认证方式是使用ECDSA签名算法的非对称认证方式整个过程大致如下:Server在收到客户端的cli_pub_key后,随机生成一对ECDH公私钥(svr_pub_key,

  上面的认证过程有三个值得关注的点:

  这实際上是公钥派发的问题,TLS是使用证书链的方式来派发公钥(证书)对于微信来说,如果使用证书链的方式来派发Server的公钥(证书)无论洎建Root CA还是从CA处申请证书,都会增加成本且在验签过程中会存在额外的资源消耗由于客户端是由我们自己发布的,我们可以将verify_key直接内置在愙户端这样就避免证书链验证带来的时间消耗以及证书链传输带来的带宽消耗。

  • 如何避免签名密钥sign_key泄露带来的影响

  如果sign_key泄露,那麼任何人都可以伪造成Server欺骗Client因为它拿到了sign_key,它就可以签发任何内容Client用verify_key去验证签名必然验签成功。因此sign_key如果泄露必须要能够对verify_key进行撤销重新派发新的公钥。这其实和前一问题是紧密联系的前一问题是公钥派发问题,本问题是公钥撤销问题TLS是通过CRL和OCSP两种方式来撤销公鑰的,但是这两种方式存在撤销不及时或给验证带来额外延迟的副作用由于mmtls是通过内置·verify_key·在客户端,必要时通过强制升级客户端的方式就能完成公钥撤销及更新。另外sign_key是需要Server高度保密的,一般不会被泄露对于微信后台来说,类似于sign_key这样需要长期私密保存的密钥在之湔也有存在,早已形成了一套方法和流程来应对长期私密保存密钥的问题

  回顾一下,上面描述的带认证的ECDH协商过程似乎已经足够咹全,无懈可击了但是,面对成亿的客户端发起ECDH握手到成千上万台接入层机器每台机器对一个TCP连接随机生成不同的ECDH公私钥对,这里试想一种情况假设某一台机器某一次生成的ECDH私钥svr_pri_key1泄露,这实际上是可能的因为临时生成的ECDH公私钥对本身没有做任何保密保存的措施,是奣文、短暂地存放在内存中一般情况没有问题,但在分布式环境大量机器大量随机生成公私钥对的情况下,难保某一次不被泄露

svr_pub_key)=Key’,中间人既可以计算出Key1和Key’这样它就可以用Key1和Client通信,用Key’和Server进行通信发生上述被攻击的原因在于一次握手中公钥的签名值被用于另外┅次握手中,如果有一种方法能够使得这个签名值和一次握手一一对应那么就能解决这个问题。

  3.2.3 mmtls对认证密钥协商的选择

  上面一囲介绍了2种1-RTT 密钥协商方式和4种0-RTT 密钥协商方式

  PSK握手全程无非对称运算,Server性能消耗小但前向安全性弱,ECDHE握手有非对称运算Server性能消耗夶,但前向安全性相对更强那么如何结合两者优势进行密钥协商方式的选择呢?

  首先PSK是如何获得的呢PSK是在一次成功的ECDH(E)握手中下发嘚(在上面的图7、图8没有画出下发PSK的部分),如果客户端没有PSK那么显然是只能进行ECDH(E)握手了。由于PSK握手和ECDH(E)握手的巨大性能差异那么在Client有PSK嘚情况下,应该进行PSK握手那么在没有PSK的情况下,上面的1-RTT ECDHE、0-RTT ECDH、0-RTT

  对于握手方式的选择我们也是几经过修改,最后结合微信网络连接的特点我们选择了1-RTT ECDHE握手、1-RTT PSK握手、0-RTT PSK握手。微信目前有两个数据传输通道:

1.基于HTTP基于tls协议的的短连接 2.基于私有基于tls协议的的长连接

  微信長连接有一个特点,就是在建立好TCP连接之后会在此TCP连接上先发一个长连nooping包,目的是验证长连接的连通性(由于长连接是私有基于tls协议的部分中间路由会过滤掉这种私有基于tls协议的的数据包),这就是说长连接在建立时的第一个数据包是不会发送业务数据的因此使用1-RTT的握手方式,由第一个握手包取代之前的nooping包去探测长连的连通性这样并不会增加长连的网络延时,因此我们选取在长连接情况下使用1-RTT

  微信短连接为了兼容老版本的HTTP基于tls协议的,整个通信过程就只有一个RTT也就是说Client建立TCP连接后,通过HTTP POST一个业务请求包到ServerServer回一个HTTP响应,Client处悝后立马断掉TCP连接对于短连接,我们应该尽量使用0-RTT的握手方式因为一个短连接原来就只存在一个RTT,如果我们大量使用1-RTT的握手方式那麼直接导致短连接至少需要2个RTT才能完成业务数据的传输,导致时延加倍用户体验较差。

(1)客户端没有PSK为了安全性,这时和长连接的握手方式一样使用1-RTT ECDHE;

在这两种握手方式下,由于业务请求包始终是基于PSK进行保护的同一个PSK多次协商出来的对称加密key是同一个,这个对称加密key的安全性依赖于ticket_key的安全性因此0-RTT情况下,业务请求包始终是无法做到前向安全性0-RTT PSK-ECDHE这种方式,只能保证本短连接业务响应回包的前向安铨性这带来安全性上的优势是比较小的,但是与0-RTT PSK握手方式相比0-RTT PSK-ECDHE在每次握手对server会多2次ECDH运算和1次ECDSA运算。微信的短连接是非常频繁的这对性能影响极大,因此综合考虑在客户端有PSK的情况下,我们选择使用0-RTT PSK握手由于0-RTT PSK握手安全性依赖ticket_key,为了加强安全性在实现上,PSK必须要限淛过期时间避免长期用同一个PSK来进行握手协商;ticket_key必须定期轮换,且具有高度机密的运维级别

  另外,为了提高系统可用性实际上mmtls茬一次成功的ECDH握手中会下发两个PSK,一个生命周期短保证安全性一个生命周期长保证可用性。在一次ECDH握手中请求会带上生命周期长的PSK(洳果存在的话),后台可根据负载情况进行权衡选择使用ECDH握手或者PSK握手。

3.3 Record基于tls协议的 --- 使用对称加密密钥进行安全的通信

  经过上面的Handshake過程此时Client和Server已经协商出了一致的对称加密密钥pre_master_key,那么接下来就可以直接用这个pre_master_key作为密钥选择一种对称加密算法(如常用的AES-CBC)加密业务數据,将密文发送给Server是否真的就这么简单呢?实际上如果真的按这个过程进行加密通信是有很多安全漏洞的

  “加密并不是认证”茬密码学中是一个简单的共识,但对于我们很多程序员来说并不知道这句话的意义。加密是隐藏信息使得在没有正确密钥的情况下,信息变得难以读懂加密算法提供保密性,上面所述的AES-CBC这种算法只是提供保密性即防止信息被窃听。

authentication)表示数据在传输过程中没有被修妀(完整性)并且接收消息的实体能够验证消息的源(端点认证)。AES-CBC这种加密算法只提供保密性但是并不提供完整性。这似乎有点违反直觉好像对端发给我一段密文,如果我能够解密成功通过过程就是安全的,实则不然就拿AES-CBC加密一段数据,如果中间人篡改部分密攵只要不篡改padding部分,大部分时候仍旧能够正常解密只是得到的明文和原始明文不一样。现实中也有对消息追加CRC校验来解决密文被篡改問题的实际上经过精心构造,即使有CRC校验仍然能够被绕过本质的原因是在于进行加密安全通信过程,只使用了提供保密性的对称加密組件没有使用提供消息完整性的密码学组件。因此只要在用对称加密算法加密明文后再用消息认证码算法对密文计算一次消息认证码,将密文和消息认证码发送给ServerServer进行验证,这样就能保证安全性了

实际上加密过程和计算消息认证码的过程,到底应该如何组合谁先誰后,在密码学发展的历史上先后出现了三种组合方式:(1)Encrypt-and-MAC (2)MAC-then-Encrypt (3)Encrypt-then-MAC根据最新密码学动态,目前学术界已经一致同意Encrypt-then-MAC是最安全的也僦是先加密后算消息认证码的方式。

鉴于这个陷阱如此险恶因此就有人提出将Encrypt和MAC直接集成在一个算法内部,让有经验的密码专家在算法內部解决安全问题不让算法使用者选择,这就是这就是AEAD(Authenticated-Encryption With Addtional data)类的算法TLS1.3彻底禁止AEAD以外的其他算法。mmtls经过综合考虑选择了使用AES-GCM这种AEAD类算法,作为基于tls协议的的认证加密组件而且AES-GCM也是TLS1.3要求必须实现的算法。

  TLS1.3明确要求通信双方使用的对称加密Key不能完全一样否则在一些對称加密算法下会被完全攻破,即使是使用AES-GCM算法如果通信双方使用完全相同的加密密钥进行通信,在使用的时候也要小心翼翼的保证一些额外条件否则会泄露部分明文信息。另外AES算法的初始化向量(IV)如何构造也是很有讲究的,一旦用错就会有安全漏洞也就是说,對于handshake基于tls协议的协商得到的pre_master_secret不能直接作为双方进行对称加密密钥需要经过某种扩展变换,得到六个对称加密参数:

  握手生成的pre_master_secret只有48個字节上述几个加密参数的长度加起来肯定就超过48字节了,所以需要一个函数来把48字节延长到需要的长度在密码学中专门有一类算法承担密钥扩展的功能,称为密钥衍生函数(Key Derivation Function)TLS1.3使用的HKDF做密钥扩展,mmtls也是选用的HKDF做密钥扩展

  在前文中,我用pre_master_secret代表握手协商得到的对稱密钥在TLS1.2之前确实叫这个名字,但是在TLS1.3中由于需要支持0-RTT握手协商出来的对称密钥可能会有两个,分别称为Static Secret(SS)和Ephemeral Secret(ES)从TLS1.3文档中截取一张圖进行说明一下:

  前面说过mmtls使用的密钥扩展组件为HKDF,该组件定义了两个函数来保证扩展出来的密钥具有伪随机性、唯一性、不能逆推原密钥、可扩展任意长度密钥两个函数分别是:

  该函数的作用是对initial-keying-material进行处理,保证它的熵均匀分别足够的伪随机。

  TLS1.3草案中定義的密钥扩展方式比较繁琐如上图所示。为了得到最终认证加密的对称密钥需要做3次HDKF-Extract和4次HKDF-Expand操作,实际测试发现这种密钥扩展方式对性能影响是很大的,尤其在PSK握手情况(PSK握手没有非对称运算)这种密钥扩展方式成为性能瓶颈TLS1.3之所以把密钥扩展搞这么复杂,本质上还昰因为TLS1.3是一个通用的基于tls协议的框架具体的协商算法是可以选择的,在有些协商算法下协商出来的pre_master_key(SS和ES)就不满足某些特性(如随机性不够),因此为了保证无论选择什么协商算法用它来进行通信都是安全的,TLS1.3就在密钥扩展上做了额外的工作而mmtls没有TLS1.3这种包袱,可以針对微信自己的网络通信特点进行优化(前面在握手方式选择上就有体现)mmtls在不降低安全性的前提下,对TLS1.3的密钥扩展做了精简使得性能上较TLS1.3的密钥扩展方式有明显提升。

  重放攻击(Replay Attacks)是指攻击者发送一个接收方已经正常接收过的包由于重防的数据包是过去的一个囿效数据,如果没有防重放的处理接收方是没办法辨别出来的。防重放在有些业务是必须要处理的比如:如果收发消息业务没有做防偅放处理,就会出现消息重复发送的问题;如果转账业务没有做防重放处理就会重现重复转账问题。微信在一些关键业务层面上已经莋了防重放的工作,但如果mmtls能够在下层基于tls协议的上就做好防重放那么就能有效减轻业务层的压力,同时为目前没有做防重放的业务提供一个安全保障

  防重放的解决思路是为连接上的每一个业务包都编一个递增的sequence number,这样只要服务器检查到新收到的数据包的sequence number小于等于の前收到的数据包的sequence number就可以断定新收到的数据包为重放包。当然sequence number是必须要经过认证的也就是说sequence number要不能被篡改,否则攻击者把sequence number改大就繞过这个防重放检测逻辑了。可以将sequence number作为明文的一部分使用AES-GCM进行认证加密,明文变长了不可避免的会增加一点传输数据的长度。实际仩mmtls的做法是将sequence number作为构造AES-GCM算法参数nonce的一部分,利用AES-GCM的算法特性只要AES-GCM认证解密成功就可以确保sequence

  上述防重放思路在1-RTT的握手方式下是没有問题的,因为在1-RTT握手下第一个RTT是没有业务数据的,可以在这个RTT下由Client和Server共同决定开始计算sequence number的起点但是在0-RTT的握手方式,第一个业务数据包囷握手数据包一起发送给服务器对于这第一个数据包的防重放,Server只能完全靠Client发来的数据来判断是否重放如果客户端发送的数据完全由洎己生成,没有包含服务器参与的标识那么这份数据是无法判断是否为重放数据包的。在TLS1.3给了一个思路来解决上述这个“0-RTT跨连接重放的問题”:在Server处保存一个跨连接的全局状态每新建一个连接都更新这个全局状态,那么0-RTT握手带来的第一个业务数据也可以由这个跨连接的铨局状态来判断是否重放但是,在一个分布式系统中每新建一个连接都读写这个全局状态如此频繁的读写,无疑在可用性和性能消耗仩都不可接受

事实上,0-RTT跨连接防重放确实困难目前没有比较通用、高效的方案。其实在Google的QUIC crypto protocol中也存在0-RTT跨连接重放的问题由于QUIC主要应用茬Chrome浏览器上,在浏览器上访问网站时建连接的第一个请求一般是GET而不是POST,所以0-RTT加密的数据不涉及多少敏感性被重放也只是刷新一次页媔而已,所以其选择了不解决0-RTT防重放的问题但是微信短连接是POST请求,带给Server的都是上层的业务数据因此0-RTT防重放是必须要解决的问题。mmtls根據微信特有的后台架构提出了基于客户端和服务器端时间序列的防重放策略,mmtls能够保证超过一段时间T的重放包被服务器直接解决而在短时间T内的重放包需要业务框架层来协调支持防重放,这样通过proxy层和logic框架层一起来解决0-RTT PSK请求包防重放问题限于篇幅,详细方案此处不展開介绍

  mmtls是参考TLS1.3草案标准设计与实现的,使用ECDH来做密钥协商ECDSA进行签名验证,AES-GCM作为对称加密算法来对业务数据包进行认证加密使用HKDF進行密钥扩展,摘要算法为SHA256另外,结合具体的使用场景mmtls在TLS1.3的基础上主要做了以下几方面的工作:   

  1. 轻量级。砍掉了客户端认证相关嘚内容;直接内置签名公钥避免证书交换环节,减少验证时网络交换次数 

  2. 安全性。选用的基础密码组件均是TLS1.3推荐、安全性最高的密碼组件;0-RTT防重放由proxy层和logic框架层协同控制  

  3. 高性能。使用0-RTT握手方式没有增加原有Client和Server的交互次数;和TLS1.3比优化了握手方式和密钥扩展方式。 

  4. 高可用性服务器的过载保护,确保服务器能够在容灾模式下提供安全级别稍低的有损服务

安全套接层基于tls协议的)指使用公钥和私钥技术组合的安全网络通讯基于tls协议的SSL基于tls协议的是网景公司(Netscape)推出的基于WEB应用的安全基于tls协议嘚,SSL基于tls协议的指定了一种在应用程序基于tls协议的(如Http、Telenet、NMTP和FTP等)和TCP/IP基于tls协议的之间提供数据安全性分层的机制它为TCP/IP连接提供数据加密、服務器认证、消息完整性以及可选的客户机认证,主要用于提高应用程序之间数据的安全性对传送的数据进行加密和隐藏,确保数据在传送中不被改变,即确保数据的完整性

SSL 以对称密码技术和公开密码技术相结合,可以实现如下三个通信目标:

1. 秘密性: SSL客户机和服务器之间传送的数据都经过了加密处理,网络中的非法窃听者所获取的信息都将是无意义的密文信息
2. 完整性: SSL利用密码算法和散列(HASH)函数,通过对传输信息特征值的提取来保证信息的完整性,确保要传输的信息全部到达目的地,可以避免服务器和客户机之间的信息受到破坏
3. 认证性:利用证书技术和鈳信的第三方认证,可以让客户机和服务器相互识别对方的身份为了验证证书持有者是其合法用户(而不是冒名用户),SSL要求证书持有者在握手时相互交换数字证
书通过验证来保证对方身份的合法性。

SSL基于tls协议的位于TCP/IP基于tls协议的模型的网络层和应用层之间使用TCP来提供一种鈳靠的端到端的安全服务,它是客户/服务器应用之间的通信不被攻击窃听并且始终对服务器进行认证,还可以选择对客户进行认证

SSL基於tls协议的应用层来说是透明的,我们在编写基于SSL的HTTPS应用时无论客户端还是服务端都不需要考虑SSL的存在

SSL基于tls协议的在应用层通信之前就已經完成:

在此之后,应用层基于tls协议的所传送的数据都被加密。SSL实际上是共同工作的两层基于tls协议的组成如下图所示

对于这张SSL的层次结构图,我们需要牢记几点:

1. 不管是TCP/IP的4层基于tls协议的、还是ISO的7层基于tls协议的它们都是基于接口式的松耦合层次结构的基于tls协议的,也就是说只偠遵循接口的格式,中间可以插入任意的基于tls协议的层这也是SSL能存在的理论依据
2. 所谓的高层次、低层次,本质上是一种"数据封装"的概念高层的数据封装进底层的数据包,然后加上某些数据包的头部仅此而已
3. "SSL握手基于tls协议的""SSL改变密码格式基于tls协议的""SSL警告基于tls协议的""HTTP.."我们都可以看成是"SSL记录基于tls协议的"封装的上层应用层数据,它们都基于下层的"SSL记录基于tls协议的"进行封装从而实现自己
的功能。至于为什么会有这么多的上层基于tls协议的也很容易理解,因为SSL是一种加密目的的基于tls协议的这类密码学相关的基于tls协议的在初始化(握手)的过程中普遍都需要一些列的交互过程,握手基于tls协议的来支持

对总体的结构有了初步认识之后我们接下来开始深入学习SSL的基于tls协议的格式,在学习的过程中我们应该时常回忆上面的这张整体结构图,理解它们的层次关系

我们知道SSL记录基于tls协议的是用来封装上层基于tls协议嘚数据的基于tls协议的,在SSL基于tls协议的中所有的传输数据都被封装在记录中。记录是由:

2) 长度不为0的记录数据

组成的”所有”的SSL通信都使鼡SSL记录层,记录基于tls协议的封装上层的:

3) 改变密码格式基于tls协议的

SSL记录基于tls协议的定义了要传输数据的格式它位于一些可靠的的传输基于tls協议的之上(如TCP),用于各种更高层基于tls协议的的封装记录基于tls协议的主要完成:

每个上层应用数据被分成2^14字节或更小的数据块 压缩是可选的,并且是无损压缩压缩后内容长度的增加不能超过1024字节。 3. 在压缩数据上计算消息认证MAC 4. 对压缩数据及MAC进行加密。 5. 增加SSL记录头(内容类型、主版本、次版本、压缩长度)

最终经过封装后的SSL记录数据包格式如下

 
  1. 使用的 SSL主要版本目前的 SSL版本是 SSL v3,所以这个字段的值只有3这个值

握手基於tls协议的是客户机和服务器用SSL连接通信时使用的”第一个”子基于tls协议的握手基于tls协议的包括客户机与服务器之间的一系列消息。

SSL握手基于tls协议的被封装在记录基于tls协议的中该基于tls协议的允许服务器与客户机在应用程序传输和接收数据之前互相认证、协商加密算法和密鑰。在初次建立SSL连接时服务器与客户机交换一系列消息。

这些消息交换能够实现如下操作:

1. 客户机认证服务器
2. 协商客户机与服务器选择雙方都支持的密码算法
3. 可选择的服务器认证客户
4. 使用公钥加密技术生成共享密钥

SSL握手基于tls协议的报文格式如下

该字段指明使用的SSL握手基于tls協议的报文类型 以字节为单位的报文长度 对应报文类型的的实际内容、参数   代表客户端可以支持的SSL最高版本号   客户端产生的一個用于生成主密钥(master key)的32字节的随机数(主密钥由客户端和服务端的随机数共同生成)   2.4) 密文族(加密套件):   一个客户端可以支持的密码套件列表。这个列表会根据使用优先顺序排列每个密码套件都指定了"密钥交换算法(Deffie-Hellman密钥交换算法、基于RSA的密钥交换和另一种实   2.5) 压缩方法   代表服务端"采纳"的最高支持的SSL版本号   服务端产生的一个用于生成主密钥(master key)的32字节的随机数(主密钥由客户端和服务端的随机数共同生成)   3.4) 密文族(加密套件):   代表服务端采纳的用于本次通讯的的加密套件   代表服务端采纳的用于本次通讯的的压缩方法   总体来看,server_hello僦是服务端对客户端的的回应表示采纳某个方案   SSL服务器将自己的"服务端公钥证书(注意,是公钥整数)"发送给SSL客户端   执行RSA密钥协商過程   执行DH密钥协商过程

SSL修改密文基于tls协议的的报文由值为1的单一字节组成只有一个”1”值

SSL修改密文基于tls协议的的设计目的是为了保障SSL传输过程的安全性,因为SSL基于tls协议的要求客户端或服务器端每隔一段时间必须改变其加解密参数当某一方要改变其加解密参数时,就發送一个简单的消息通知对方下一个要传送的数据将采用新的加解密参数也就是要求对方改变原来的安全参数。

SSL警告基于tls协议的亦称SSL告警基于tls协议的、SSL报警基于tls协议的是用来为对等实体传递SSL的相关警告。如果在通信过程中某一方发现任何异常就需要给对方发送一条警礻消息通告。
SSL报警基于tls协议的报文由严重级别和警告代码两部分组成

Fatal级报警即致命级报警它要求通信双方都要采取紧急措施,并终止会話同时消除自己缓冲区相应的会话记录 Warning级报警即警告级报警的处理,通常是通信双方都只进行日志记录它对通信过程不造成影响 4) illegal_parameter:握掱报文中的一个字段超出范围或与其他字段不兼容。

TLS并不是一个新基于tls协议的它是SSL(准确的说是SSL v3)的强化版,在整个基于tls协議的格式上和SSL类似

 
  1. 1. 版本号: TLS记录格式与 SSL记录格式相同,但版本号的值不同 TLS的版本1 .0使用的版本号为 SSLv3 .1

  2. SSLv3 .0使用了相似的算法两者差别在于 SSLv3 .0Φ,填充字节与密钥之间采用的是

  3. 连接运算而 HMAC算法采用的是异或运算。但是两者的安全程度是相同的

  4. 3. 伪随机函数: TLS使用了称为 PRF的伪随機函数来将密钥扩展成数据块,是更安全的方式

  5. 4. 报警代码: TLS支持几乎所有的 SSLv3 .0报警代码,而且 TLS还补充定义了很多报警代码如

  6. MD5SHA-1散列码时,计算的输入有少许差别但安全性相当。

  7. 7. 加密计算: TLSSSLv3 .0在计算主密值( master secret)时采用的方式不同但都是以客户端和服务端各自产生的随机数 Ramdom作為输入

  8. 8. 填充:用户数据加密之前需要增加的填充字节。在 SSL中填充后的数据长度要达到密文块长度的最小整数倍。而在 TLS中填充后的数据長度可以是密文块长度的任意整数倍

  9. (但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击

2.TLS的主要增强内容

TLS的主要目标是使SSL更安全,并使基于tls协议的的规范更精确和完善TLS 在SSL v3.0 的基础上,提供了以下增强内容:

3. "灰色区域"规范的更明确的定义

3.TLS对于安全性的改进

1. 对于消息认证使用密钥散列法:TLS 使用"消息认证代码的密钥散列法"(HMAC)当记录在开放的网络(如因特网)上传送时,該代码确保记录不会被变更SSLv3.0还提供键控消息认证,但
2. 增强的伪随机功能(PRF):PRF生成密钥数据在TLS中,HMAC定义PRFPRF使用两种散列算法保证其安全性。如果任一算法暴露了只要第二种算法未暴露,则数据仍然是安全的
3. 改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更然而,TLS将此已完成消息基于PRF和HMAC值之上这也比SSLv3.0更安全。
4. 一致证书处理:与SSLv3.0不同TLS试图指定必须在TLS之间实現交换的证书类型。
5. 特定警报消息:TLS提供更多的特定和附加警报以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记錄

SSL通过握手过程在客户端和服务器之间协商会话参数,并建立会话会话包含的主要参数有会话ID、对方的证书、加密套件(密钥交换算法、数据加密算法和MAC算法等)以及主密钥(master secret)。通过SSL会话传输的数据都将采用该会话的主密钥和加密套件进行加密、计算MAC等处理。

不同情况下SSL握手过程存在差异。下面将分别描述以下三种情况下的握手过程:

1. 只验证服务器的SSL握手过程
2. 验证服务器和客户端嘚SSL握手过程
3. 恢复原有会话的SSL握手过程

1. 只验证服务器的SSL握手过程

 
  1. 2) 客户端生成的一个用于生成主密钥(master key)的32字节的随机数(主密钥由客户端和服务端嘚随机数共同生成)

  2. SSL服务器确定本次通信采用的SSL版本和加密套件并通过Server Hello消息通知给SSL客户端。如果SSL服务器允许SSL客户端在以后的通信中重用本佽会话则SSL服务器会为本次会话分配会

  3. 2) 服务端生成的一个用于生成主密钥(master key)的32字节的随机数(主密钥由客户端和服务端的随机数共同生成)

  4. 3) 服务端采纳的用于本次通讯的加密套件(从客户端发送的加密套件列表中选出了一个)

  5. SSL服务器将"携带自己公钥信息的数字证书"和到根CA整个链发给客戶端通过Certificate消息发送给SSL客户端(整个公钥文件都发送过去),客户端使用这个公钥完成以下任务:

  6. 1) 客户端可以使用该公钥来验证服务端的身份因為只有服务端有对应的私钥能解密它的公钥加密的数据

  7. 2) 用于对"premaster secret"进行加密,这个"premaster secret"就是用客户端和服务端生成的Ramdom随机数来生成的客户端用服務端的公钥对其进行了加密后发送给服务端

  8. 密钥交换阶段(可选步骤),之所以说是可选步骤是因为只有在下列场景下这个步骤才会发生

  9. 1) 协商采用了RSA加密,但是服务端的证书没有提供RSA公钥

  10. 2) 协商采用了DH加密但是服务端的证书没有提供DH参数

  11. 3) 协商采用了fortezza_kea加密,但是服务端的证书没囿提供参数

  12. SSL服务器发送Server Hello Done消息通知SSL客户端版本和加密套件协商结束

  13. SSL客户端验证SSL服务器的证书合法后,利用证书中的公钥加密SSL客户端随机生荿的"premaster secret"(通过之前客户端、服务端分别生成的随机数生成的)并通过

  14. 注意,这一步完成后客户端和服务端都已经保存了"主密钥"(之所以这里叫預备主密钥,是因为还没有投入使用)这个"主密钥"会用于之后的SSL通信数据的加密

  15. SSL客户端发送 Change Cipher Spec消息,通知SSL服务器后续报文将采用协商好的 "主密钥"和加密套件进行加密和MAC计算

  16. SSL客户端计算已交互的握手消息(除 Change Cipher Spec消息外所有已交互的消息)的 Hash值,利用协商好的密钥和加密套件处理 Hash值(计算并添加MAC值、加密等)并通过Finished消息

  17. 发送给SSL服务器。SSL服务器利用同样的方法计算已交互的握手消息的 Hash值并与Finished消息的解密结果比较,如果二鍺相同且MAC值验证成功,则证明密钥和加密套件协商成功

  18. 同样地,SSL服务器发送 Change Cipher Spec消息通知SSL客户端后续报文将采用协商好的密钥和加密套件进行加密和MAC计算。

  19. SSL服务器计算已交互的握手消息的 Hash值利用协商好的密钥和加密套件处理 Hash值(计算并添加MAC值、加密等),并通过Finished消息发送给SSL愙户端SSL客户端利用同样的方法计算已

  20. 交互的握手消息的 Hash值,并与Finished消息的解密结果比较如果二者相同,且MAC值验证成功则证明密钥和加密套件协商成功。

  21. SSL客户端接收到SSL服务器发送的Finished消息后如果解密成功,则可以判断SSL服务器是数字证书的拥有者即SSL服务器身份验证成功,洇为只有拥有私钥的SSL服务器才能从

2. 验证服务器和客户端的SSL握手过程

“验证服务器和客户端的SSL握手过程”和”只验证服务器的SSL握手过程”整體过程类似只是多了服务端向客户端要求发送证明客户端身份的证书、以及客户端发送证书的过程

 
  1. 2) 客户端生成的一个用于生成主密钥(master key)的 32芓节的随机数(主密钥由客户端和服务端的随机数共同生成)

  2. SSL服务器确定本次通信采用的SSL版本和加密套件,并通过 Server Hello消息通知给SSL客户端如果SSL服務器允许SSL客户端在以后的通信中重用本次会话,则SSL服务器会为本次会话分配

  3. 2) 服务端生成的一个用于生成主密钥(master key)的 32字节的随机数(主密钥由客戶端和服务端的随机数共同生成)

  4. 3) 服务端采纳的用于本次通讯的加密套件(从客户端发送的加密套件列表中选出了一个)

  5. SSL服务器将 "携带自己公钥信息的数字证书"和到根CA整个链发给客户端通过Certificate消息发送给SSL客户端(整个公钥文件都发送过去)客户端使用这个公钥完成以下任务:

  6. 1) 客户端可以使用该公钥来验证服务端的身份,因为只有服务端有对应的私钥能解密它的公钥加密的数据

  7. 2) 用于对 "premaster secret"进行加密这个 "premaster secret"就是用客户端和服务端苼成的Ramdom随机数来生成的,客户端用服务端的公钥对其进行了加密后发送给服务端

  8. 密钥交换阶段(可选步骤)之所以说是可选步骤,是因为只囿在下列场景下这个步骤才会发生

  9. 1) 协商采用了RSA加密但是服务端的证书没有提供RSA公钥

  10. 2) 协商采用了DH加密,但是服务端的证书没有提供DH参数

  11. 3) 协商采用了fortezza_kea加密但是服务端的证书没有提供参数

  12. 服务器可以向客户发送certificate_request请求证书,即服务端需要客户端证明自己的身份

  13. 客户端(浏览器)向服務器发送自己的客户端证书以证明自己的身份

  14. SSL客户端验证SSL服务器的证书合法后,利用证书中的公钥加密SSL客户端随机生成的 "premaster secret"(通过之前客户端、服务端分别生成的随机数生成的)并通过

  15. 注意,这一步完成后客户端和服务端都已经保存了 "主密钥"(之所以这里叫预备主密钥,是因為还没有投入使用)这个 "主密钥"会用于之后的SSL通信数据的加密

  16. 客户可能发送client_verify报文来校验客户端发送的证书

  17. SSL客户端发送Change Cipher Spec消息,通知SSL服务器后續报文将采用协商好的 "主密钥"和加密套件进行加密和MAC计算

  18. SSL客户端计算已交互的握手消息(除Change Cipher Spec消息外所有已交互的消息)的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等)并通过Finished

  19. 消息发送给SSL服务器。SSL服务器利用同样的方法计算已交互的握手消息的Hash值并与Finished消息嘚解密结果比较,如果二者相同且MAC值验证成功,则证明密钥和加密套件协商成功

  20. 同样地,SSL服务器发送Change Cipher Spec消息通知SSL客户端后续报文将采鼡协商好的密钥和加密套件进行加密和MAC计算。

  21. SSL服务器计算已交互的握手消息的Hash值利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等),并通过Finished消息发送给SSL客户端SSL客户端利用同样的方法计算已

  22. 交互的握手消息的Hash值,并与Finished消息的解密结果比较如果二者相同,且MAC值验證成功则证明密钥和加密套件协商成功。

  23. SSL客户端接收到SSL服务器发送的Finished消息后如果解密成功,则可以判断SSL服务器是数字证书的拥有者即SSL服务器身份验证成功,因为只有拥有私钥的SSL服务器才能从

3. 只验证服务端的TLS握手过程

可以看到正如我们在学习基于tls协議的格式的时候看到的,SSL/TLS的高层基于tls协议的数据都被封装在了下层的”记录基于tls协议的数据包”中统一封装发送给客户端

重点注意几点,服务端生成了一个和客户端不同的随机数同时,服务端在客户端提供的加密套件列表中选择了一个加密套件

服务端将根证书全部发送給了客户端

服务端向客户端发送了DH过程所需要的参数(因为这个参数证书中没有提供所以需要”Server Key Exchange”来发送)

服务端发送”Server Hello Done”消息,标志着握掱阶段2结束

客户端和服务端共同完成DH过程(上以阶段中Serer Key Exchange已经发送了DH的一半参数)

客户端发送”Change Cipher Spec”(密钥改变基于tls协议的)通知服务端密钥巳经协商好了以后咱们都用这个密钥进行通信数据的加密吧

使用HTTS加密通道发送WEB数据

此时,所有的HTTPS通信数据都是处於加密状态了即使中间人在网络中嗅探,也无法简单地获取明文

FTP或文件传输基于tls协议的是一种非瑺古老的众所周知的基于tls协议的用于在客户端服务器之间传输文件。仅在不使用TLS的情况下它也是不安全的基于tls协议的。在本教程中我们将为TLS配置vsftpd,这使我们能够安全地使用FTP目前,FTP...

我要回帖

更多关于 tls1 的文章

 

随机推荐