1、SSL的发展历史
SSL/TLS协议发展历史参看下表,更详细的发展历史参看维基百科的SSL/TLS协议发展历史。
Protocol Year RFC Description
SSL 1.0 1994 NetScape公司设计1.0版 但是未发布
SSL 2.0 1995.02 NetScape公司发布SSL 2.0版
SSL 3.0 1996 RFC 6101 NetScape公司发布SSL 3.0版
TLS 1.0 1999 RFC 2246 IETF将SSL标准化 改名为TLS 发布1.0版
TLS 1.1 2006.04 RFC 4346 发布TLS1.1版
TLS 1.2 2008.08 RFC 5246 发布TLS1.2版
TLS 1.3 TLS 1.3还是一个互联网草案 待发布
目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。值得一提的是iOS9的App,需将HTTP连接升级到HTTPS,并且TLS版本不得低于1.2(当然升级为HTTPS并非必须的)。
2、TLS1.2与1.1的差异
a.在伪随机函数中合并使用MD5和SHA-1算法的做法被在伪随机函数中指定密码协议族的方法所取代。本文中所有的密码协议族使用P_SHA256。
b.在数字签名要素中合并使用MD5和SHA-1算法的做法被单独的hash算法取代。现在的签名要素包含一个显式指定所用hash算法的域。
c.对客户端和服务器的能力进行实质性的清理,以便指定他们能接受的hash和签名算法。这样也会减小使用以前版本TLS中的签名和hash算法的约束。
d.增加了对“以其它数据模式进行认证加密”的支持。
e.增加了对TLS扩展的定义和AES协议族的支持。
f.对加密的预主密钥的版本号进行更严格的检查。
g.严格限定了一些需求。
h.Verifi_data的长度现在取决于密码协议(默认仍然是12)。
i.清除了对Bleichenbacher/Klima攻击防御的描述。
j.在很多情况下必须发送警报消息。
k.在发出一个“证书请求”消息之后,如果客户端没有收到证书,则必须发送一个空证书列表。
l.TLS_RSA_WITH_AES_128_CBC_SHA现在是一个强制实现的密码协议族。
m.增加了HMAC-SHA256密码协议族。
n.移除了IDEA和DES协议族,它们已经不被赞成使用,且会在一个单独的文档中说明。
o.对SSLv2后向兼容hello的支持现在是“可以”而非“应该”(支持的方式为回应”SHOULD NOT“);将来这种支持很可能成为“”不应该“。
p.在演示语言中增加受限的”通过“,以便允许多种情况的arms拥有相同的编码。(原文:Added limited "fall-through" to the presentation language to allow multiple case arms to have the same encoding.)
q.增加了章节描述关于实现上的易犯的错误
r.通常的澄清和编辑工作
3、TLS1.2的设计目标
TLS协议的目标按照优先级排列如下:
a.密码安全:TLS应当被用于在通信双方之间建立一个安全连接。
b.互操作性:不相关的程序员们应当能够在不了解他人代码的情况下使用TLS开发出能成功地交换密码参数的应用。
c.可扩展性:TLS致力于提供一个框架,新的公钥和块加密方法能够作为必要内容被合并进去。这样也会实现两个子目标:阻止了创造新协议的需要(和引入可能存在新弱点的风险)和避免了实现一整套新安全库的需要。
d.相对效率:密码操作趋于高CPU消耗,尤其是公钥操作。正因如此,TLS协议已经结合了一个可选的会话缓存机制以减小连接(that need to be established from scratch)的数量。此外,关于减少网络活动(译者注:应该指的是流量)也获得了关注。
4、密钥生成
记录协议需要一个算法从握手协议提供的安全参数中生成当前连接状态(见附录A.6)所需的密钥。
主密钥被扩张为一个安全字节序列,它被分割为一个客户端写MAC密钥,一个服务端写MAC密钥,一个客户端写加密密钥,一个服务端写加密密钥。它们中的每一个都是从字节序列中以上述顺序生成。未使用的值是空。一些AEAD加密可能会额外需要一个客户端写IV和一个服务端写IV(见6.2.3.3节)。
生成密钥和MAC密钥时,主密钥被用作一个熵源。
为了生成密钥数据,计算
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.server_random +
SecurityParameters.client_random);
直到产生足够的输出。然后,key_block会按照如下方式分开:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
目前,client_write_IV和server_write_IV只能由[AEAD]3.2.1节中描述的隐式nonce技术生成。
实现注记:当前定义的密码协议族使用最多的是AES_256_CBC_SHA256。它需要2 x 32字节密钥和2 x 32字节MAC密钥,它们从128字节的密钥数据中产生。
5、TLS协议的组成
TLS协议可以分为3个子协议:alert协议、change_cipher_spec协议(变更密码协议)、handshake协议(握手协议)
5.1、变更密码协议
变更密码规范协议存在的目的是通告加密策略的改变。这个协议由单个消息组成,这个消息会被在当前(并非挂起)连接状态下被加密和压缩。这个消息由一个值为1的单个字节构成。
ChangeCipherSpec消息可以被client和server发送,以通告接收方随后的记录消息将会由新协商的密码规范和密钥所保护。接收到这个消息会导致接收者指示记录层立即将读挂起状态复制到读当前状态。发送此消息后,发送这必须立即指示记录层将写挂起状态转变为写活动状态(见6.1节)。ChangeCipherSpec消息在握手过程中发送,但要在安全参数协商完毕之后,且在验证结束消息发送之前。
注意:如果发生一个重握手事件而连接的数据还在流动,通信的双方可能使用旧的CipherSpec继续发送数据。然而,一旦ChangeCipherSpec被发送了,新的CipherSpec必须被使用。先发送ChangeCipherSpec的一方不知道另外一方已经完成了新密钥数据的计算(例如,如果它执行一个耗时的公钥操作)。因此,在接收方必须缓存数据时会存在一个小的窗口时间。事实上,在现代机器中这个间隔会相当短
5.2、握手协议
5.2.1、握手流程
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
5.2.2、消息类型
enum {
hello_request(0),
client_hello(1),
server_hello(2),
certificate(11),
server_key_exchange (12),
certificate_request(13),
server_hello_done(14),
certificate_verify(15),
client_key_exchange(16),
finished(20), (255)
} HandshakeType;
5.2.3、Hello Request
A、HelloRequest消息可以在任何时间由server发送
B、HelloRequest是一个简单的通告client应该开始重协商流程。 在响应过程中,client应该在方便的时候发送一个ClientHello消息
C、server不应该在client发起连接后立即发送一个HelloRequest
D、如果client当前正在协商一个会话时这个消息会被client忽略,或client希望响应一个no_renegotiation警报
E、如果server发送了一个HelloRequest但没有收到一个ClientHello响应,它应该用一个致命警报关闭连接。
F、这个消息不能被包含在握手消息中维护的消息hash中, 也不能用于结束的消息和证书验证消息
5.2.4、Client Hello
A、当一个client第一次连接一个server时, 它被要求发送ClientHello作为第一个消息。 Client也能发送一个ClientHello作为对HelloRequest的响应,或用于自身的初始化以便在一个已有连接中重新协商安全参数
B、random_bytes由一个安全的随机数生成器产生的28个字节数据
C、密码族列表, 在ClientHello消息中从client传递到server, 以client所倾向的顺序(最喜爱的在最先)包含了client所支持的密码算法. 每个密码族定义了一个密钥交互算法, 一个块加密算法(包括密钥长度), 一个MAC算法, 和一个随机数生成函数
D、compression_methods由于暴露出压缩算法导致的漏洞,已被禁用
E、client_versionclient愿意在本次会话中使用的TLS协议的版本. 这个应当是client所能支持的最新版本(值最大)
5.2.5、Server Hello
A、Server将发送这个消息作为对ClientHello消息的响应, 当它能够找到一个可接受的算法集时. 如果不能找到这样的算法集, 它会发送一个握手失败警报作为响应.
B、 server_version 这个域将包含client在client hello消息中建议的较低版本和server所能支持的最高版本.
5.2.6、Server Certificate
A、server必须发送一个Certificate,无论何时协商一致的密钥交换算法使用证书进 行认证(包括除DH_anon外本文中定义的所有密 钥交互算法)。 这个消息一直是 紧随在ServerHello消息之后
B、这个消息传达了server的证书链给client.证书必须适用于已协商的密码族的密钥交互算法和任何已协商的扩展。
C、证书类型必须是X.509v3
5.2.7、Server密钥交换消息
A、ServerKeyExchange消息由server发送, 但仅在server证书消息(如果发送了)没有包含足够的数据以允许client交换一个预密钥时
B、DHE_DSS、DHE_RSA、DH_anon、ECDHE_ECDSA、ECDHE_RSA、ECDH_anon这个限制对于如下的密钥交换算法是成立的
C、RSA、DH_DSS、DH_RSA、ECDH_ECDSA、ECDH_RSA密钥交换算法发送ServerKeyExchange是非法的
D、其它的密钥交换算法, 如在[TLSECC]中所定义的那些, 必须指定是否发送ServerKeyExchange; 如果消息发送了, 则必须指定发送内容.
E、这个消息传递了密码信息以允许client就预主密钥进行交互: 一个client用于完成一个密钥交换的Diffie-Hellman公钥(结果就是预主密钥)或一个其它算法的公钥
F、一般要传递的是:一个 Diffie-Hellman 公钥,或者一个其他算法(例如RSA)的公钥。
G、更为详细的介绍,见rfc tls1.2
5.2.8、证书请求
A、一个非匿名的server能有选择地请求一个client发送的证书, 如果选定的密码族合适的话
B、如果发送必须紧随ServerKeyExchange消息之后
5.2.9、Server Hello Done
A、ServerHelloDone消息已经被server发送以表明ServerHello及其相关消息的结束. 发送这个消息之后, server将会等待从client发送的响应
B、这个消息意味着server发送完支持密钥交换的消息, client能继续它的密钥交换处理
C、在收到ServerHelloDone消息之后, client应当验证server提供的是否是有效的证书, 如果有要求的话, 检查server hello参数是否可以接受
5.2.10、Client证书
上传client证书,进行身份认证
5.2.11、Client密钥交换消息
A、这个消息一直由client发送. 如果被发送的话, 它必须紧随着client证书消息. 否则, 它必须是在client收到ServerHelloDone后发送的第一个消息
B、在这个消息中设置了预主密钥, 这个或者通过RSA加密后直接传输, 或者通过传输Diffie-Hellman参数来允许双方协商出一致的预主密钥
C、如果RSA被用于密钥协商和认证, client会生成一个48字节的预主密钥,使用server证书中的公钥加密,然后以一个加密的预主密钥消息发送
D、client发送了一个证书其中包含了一个合适的Diffie-Hellman密钥(用于fixed_dh类型的client认证),则Yc是隐式的且不需要再次发送。这种情况下,client密钥交换消息会被发送,单必须是空。如果没有传递client证书,则必须发送一个自己的公钥给服务器
5.2.12、Certificate Verify
A、当需要做客户端认证时,客户端发送CertificateVerify消息,来证明自己确实拥有客户端证书的私钥
B、当发送时,它必须紧随着client密钥交换消息
C、这条消息仅仅在客户端证书有签名能力的情况下发送(就是说,除了含有固定 Diffie-Hellman 参数的证书以外的证书)
5.2.13、Finished
A、一个结束消息一直会在一个change cipher spec消息后立即发送
B、结束消息的接收者必须验证内容是正确的。一旦一方已经发送了结束消息且接收并验证了对端发送的结束消息
C、对于由client发送的结束消息,字符串是"client finished". 对于由server发送的结束消息,字符串是"server finished"
D、如何验证见rfc tls1.2
5.2.14、handshake — NewSessionTicket
A、SessionTicket 定义在 RFC5077 标准里面,2008年发布
B、服务器把本地的 session 状态存入一个ticket中,ticket会被加密,并被MAC保护,无法篡改,加密和算MAC用的key只有服务器知道。 加密并MAC过的ticket用 NewSessionTicket 消息分发给客户端,NewSessionTicket 消息应该在 ChangeCipherSpec 消息之前,在服务器验证通过客户端的Finished消息之后发送
5.3、Alert协议
6、application data协议