作者:drinkey
以前读RFC时总结的一篇文章,主要介绍了SSL/TLS协议的相关知识,包括协议本身以及简单的密码学概念,以及用实例解析了HTTP over SSL的协商过程,在最后简要列出了SSL的安全问题。
RFC-2246: The TLS Protocol Version 1.0
详细讲述了TLS1.0的协议,TLS协议提供了一种Internet安全通信方式,该协议允许客户端和服务端通信,并保证消息不被监听,篡改和伪造。
RFC-2818: HTTP Over TLS
描述了如何使用TLS协议来保证HTTP通信的安全性
RFC-3749: Transport Layer Security Protocol Compression Methods
描述了TLS压缩的几种方式
RFC-5216: The EAP-TLS Authentication Protocol
EAP-TLS认证协议
RFC-5246: The Transport Layer Security (TLS) Protocol Version 1.2
TLS1.2协议文档,在RFC2246基础上有所发展
最初SSL协议是由netscape开发,并集成到浏览器中,用于保护HTTP传输安全性,作为在传输层和应用层之间的一层,对更多的需要保护数据安全性的协议进行封装。IETF以SSL协议为基础,提出了一种新的协议:TLS,建立在SSL V3.0的基础上,是SSL 3.0的后续版本,已经开始在实际应用中使用。
虽然TLS和SSL不能互操作,仅仅是因为他们使用的加密算法和MAC算法不同,协议本身差别非常细微。RFC-2246是IETF提出的第一个版本,被称作TLS v1.0,目前最新的版本是TLS v1.2,在RFC-5246中描述了其细节问题。
以下根据RFC5246,介绍SSL
协议由两层构成: TLS Record Protocol
和 TLS Handshake Protocol
。
TLS Record Protocol
处于较低的一层,基于一些可信任的协议,如TCP,为高层协议提供数据封装、压缩、加密等基本功能的支持。它保证了通信的两个基本安全属性:
1.保密连接。数据传输使用对称加密算法,如AES,RC4等,该对称加密算法的密钥对于每个连接是唯一的,基于密钥协商协议生成,比如 TLS handshake protocol
, Record Protocol
也可以不使用加密。
2.可信连接。消息的传输包括了基于密钥的消息认证码(keyed MAC),使用安全Hash函数计算MAC,用于完整性检查。 Record Protocol
也可以不使用MAC,但是这种模式只用于安全参数协商时。
Record Protocol
用于封装多种高层的协议,其中一个种就是 TLS handshake protocol
,这种协议允许客户与服务器相互认证,在应用程序通信前,协商加密算法和加密密钥。 TLS handshake protocol
保证了连接的三个基本安全属性:
为了便于更好的认识和理解SSL协议,这里着重介绍SSL协议的握手协议,mail.qq.com支持SSL协议,以下结合实例,介绍SSL握手协议。数据包使用Wireshark抓取。对于文中提到的密码学术语,在文章第5节有简单解释,可对照阅读。
SSL 协议既用到了非对称公钥加密技术又用到了对称加密技术,对称加密技术使用于Record层,用于对传输的数据进行加密,公钥加密技术使用于Handshake协议,提供了身份认证的功能。
SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证,本实例中只有客户端验证服务端,服务端并没有对客户端进行验证,一般相互进行身份认证的情况在登录银行系统时会用到。
下面根据抓取到的数据包,分析浏览器访问mail.qq.com时使用SSL协议的过程:
Cipher Specs字段是一个枚举类型,说明了客户端所支持算法,每个Cipher Spec指定了一个加密组合,从下图可以看出,SSL与TLS的很显著的区别就是,TLS支持了更多更先进更安全的加密组合,如下图所示:
Random
是服务端产生的随机数,根据一个随机种子生成,这里的随机种子是gmt_unix_time,根据这个时间,使用伪随机数函数(PRF)生成一个32字节的random_bytes。
Session ID
是一组任意字节数的序列,由server选出,用于识别连接是活动状态还是可恢复状态。
Cipher Suite
指定了服务端选定的加密组合,这里选出的加密组合是TLS_RSA_WITH_AES_256_CBC_SHA,RSA作为认证算法,256位的AES分组加密算法作为Record层加密payload使用的算法,SHA作为消息认证码算法,用于保证消息的完整性,防止消息被篡改。
Compress Method
表明了使用的压缩算法,Record层接收高层协议的数据时,会将数据进行分片,前面已经提到过,对于每个分片可以选择使用一定压缩算法来提高加密和传输效率,这里没有使用压缩算法,所以是null。
接着,服务端返回了证书,证书使用x.509格式,供客户端验证其身份,同时发送一个Server Hello Done消息。如下图所示:
③客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的 CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。
④用户端随机产生一个用于后面通讯的密钥,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密,然后将加密后的“预主密钥”传给服务器( Client key exchange
)。该过程内容如下图所示:
由于预主密钥的传输使用RSA进行了加密,所以无法在抓取的数据包中显示出来(在上图中的 Encrypted Handshake Message
),从而保证了握手过程的保密性。
⑤如果服务端要求客户的身份认证(在握手过程中为可选,本例中没有该步骤),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的预主密码( Premaster secret
)一起传给服务端。
⑥如果服务端要求客户的身份认证,服务端必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的CA 是否可靠,发行CA 的公钥能否正确解开客户证书的发行 CA 的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务端将用自己的私钥解开加密的预主密码,然后执行一系列步骤来产生主密钥( Master secret
)(客户端也将通过同样的方法产生相同的主通讯密码)。
如果服务端没有进行步骤5,服务端端收到客户端发送的使用服务端公钥加密的预主密钥,用私钥解开加密的预主密钥,执行一系列函数,生成会话的主密钥,客户端也进行相同的操作生成主密钥。
⑦服务器和客户端拥有了相同的主密钥,双方使用之前协商的对称加密算法,并使用主密钥作为密钥,用于 SSL 协议的安全数据通讯的加解密通讯。同时在 SSL 通讯过程中还要维护数据通信的完整性,防止数据通讯中的任何变化,通过消息认证码来保证。
⑧客户端向服务器端发出信息( Change cipher spec
),指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。
⑨服务器向客户端发出信息( Change Cipher Spec
),指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。
⑩SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。该过程的数据包如下图所示:
从此过程开始,TLS Record层使用Application Data Protocol通信,其Content-type字段变为HTTP,这个字段记录了上层协议的协议类型,以便数据提交到对方的TLS Record层后,对数据进行组装,并交付给上层协议处理。
以上详细阐述了基于TLS的HTTP协议(HTTPS)客户端与服务端建立连接和握手的过程,以下对一些用到的密码知识作为补充,进行简单的介绍:
PRF
:伪随机数生成函数,用于生成任意大小的随机序列。一般使用时间作为初始化的随机种子,通过PRF生成随机序列,如果序列的长度不符合要求,则使用Hash函数对序列进行散列运算,经过几轮迭代知道序列长度满足要求为止。一个好的PRF可以保证序列的随机性最大化,防止猜测。
对称加密算法
:如AES,DES,RC4。加密和解密的两个过程使用相同的密钥,通过加密和解密函数对数据进行操作,从而达到加密数据和解密数据的目的。
公钥加密算法
:如DSA,RSA。通信双方共享各自的公钥,传输时使用对方的公钥对数据进行加密,接收方收到后,用自己的私钥对数据进行解密。公钥加密算法也被称为非对称加密算法,因为加密和解密使用不同的密钥。公钥算法的数学依据是大素数的分解问题,理论上很难分解一个足够大素数。常做认证和签字用。
分组密码
:很多对称加密算法都是分组加密,先将需要加密的数据进行分组和填充,再将每个分组使用加密函数进行加密,经过一些置换和迭代,得到固定长度的输出。
Hash函数
:如SHA,MD5。散列函数,具有单向性。散列函数对消息进行摘要,并经过迭代,得到固定长度的输出。消息的一个字节的变化对Hash函数的输出都会有很大的影响。
MAC
:消息认证码,由Hash函数对消息进行摘要得到,由于Hash函数的特性,可以提供对消息完整性的验证,一般随消息一起发出。
TLS协议大量的使用了以上密码算法,从而保证了数据的完整性和保密性,密码学是TLS协议安全的基础,任何一种使用到的密码算法被破解,将直接影响TLS协议的安全性。
TLS协议并不是牢不可破的,使用了TLS的HTTP协议不一定安全。由于TLS协议中有很多可选项,甚至可以选择Record层是否使用加密,如果没有很好的配置,那么TLS也不能保证传输的安全性。
2009 blackhat con中Marsh Ray提到了Renegotiating TLS attack,由于TLS renegotiating的逻辑漏洞,造成在理想环境下,可以实施中间人攻击,这个攻击是非常巧妙的,主要是利用了TLS/SSL 3.0重置加密算法机制和HTTP协议请求头的key、value结构,实现了多次数据的组合以完成自己想要的请求。
主要步骤如下:
1). 攻击者连接目标站点完成SSL握手称为session 1,并发送 GET /adduser.jsp?u=test&passwd=123 HTTP/1.1/r/nFVCK:
之类的数据包。
2). 攻击者劫持被攻击者访问目标站点的数据,在session 1中转发被攻击者与目标服务器之间的SSL握手,被攻击者和目标服务器完成握手称为session 2。
3). 目标站点和被攻击者通过攻击者的转发完成握手,在session 2中被攻击者发送自己的请求数据到目标服务器,类似于 GET / HTTP/1.1/r/nHost: www.xxx.com/r/nAccept: */*/r/nCookie: admin=1/r/n/r/n
之类的数据。
4). 目标站点在一个SSL Session 1中接收到一个新的SSL Client Hello时,会认为客户端是在要求重新生成密钥,因为在目标服务器看来session 2也是攻击者发过来的,而且是相同的TCP session中。最终导致目标服务器认为session 2是session 1密钥重置之后的延续,会将两次的数据组合到一起。
5). 最终数据如下: GET /adduser.jsp?u=test&passwd=123 HTTP/1.1/r/nFVCK: GET / HTTP/1.1/r/nHost: www.xxx.com/r/nAccept: */*/r/nCookie: admin=1/r/n/r/n
。FVCK字段服务器不认识,真实请求 GET / HTTP/1.1
当成了 FVCK
字段的值,一起被忽略掉,攻击者成功的执行了添加WEB系统用户的操作
详细介绍参照Marsh Ray的原作:
http://extendedsubset.com/Renegotiating_TLS.pdf
文档的最后展示了中间人攻击的结果,成功获得了TLS协议上层协议的内容。
2014年Google公布了SSLv3的漏洞,CVE-2014-3566,代号POODLE(Padding Oracle On Downgraded Legacy Encryption),目前只有通过服务端禁用SSLv3.0协议来防止此攻击的发生。
知名的开源安全软件OpenSSL同样在2014年同样也爆出了Heart bleed漏洞,造成攻击者可以直接读取内存中的数据。