SSL
什么是SSL:安全套接字层,网景公司研发,保障数据传输安全,广泛应用于Web浏览器和服务器之间的身份认证和加密数据传输
SSL协议分为两层
- SSL记录协议:建立在TCP之上,为高层协议提供数据封装、加密、压缩
- SSL握手协议:建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等
SSL协议保证网络通信的安全和数据的完整性通过两种手段实现:身份认证、数据加密
SSL协议是独立协议,其他应用层协议也可以使用,如SMTP和TELNET
HTTPS不是独立协议,其本质是HTTP协议+SSL+TLS,即HTTP先和SSL通信,然后再由SSL和TCP通信
TLS握手解析
密钥交换协议
TLS握手的目的是为了协商对称密钥,传统的密钥协商过程如下:
1、客户端发起连接请求
2、服务端回复自己的证书
3、客户端使用证书链机制验证证书的有效性;生成对称密钥S,使用证书中包含的公钥加密,发送给服务端
4、服务端使用私钥解密得到对称密钥S,然后双方使用S进行对称加密传输
在私钥不泄露的情况下,第三方无法解密内容
私钥参与密钥交换,不满足前向安全性
前向安全性:长期使用的主密钥泄漏不会导致过去的会话密钥泄漏。前向保密能够保护过去进行的通讯不受密码或密钥在未来暴露的威胁。如果系统具有前向保密性,就可以保证在私钥泄露时历史通讯的安全,即使系统遭到主动攻击也是如此
DH密钥交换
流程如下:
1、客户端发起请求
2、服务端生成私钥a,选定参数p和g,计算A=g^a mod p
,发送A,p,g给客户端
3、客户端生成私钥b,计算B=g^b mod p K=A^b mod p
,K就是主密钥,将B发送给服务端
4、服务端计算主密钥K=B^a mod p
若将计算过程替换为椭圆曲线的方式,就产生了ECDH和ECDHE两个算法,由于ECDH的非前向安全性,目前已经废弃
证书认证机制
CA机构
CA是证书的签发机构,通过WebTrust国际安全审计认证,就可以将自己颁发的证书预装到主流浏览器中,成为受信的根证书。CA负责签发证书、认证证书、管理已颁发证书的机关
全球的主流的CA机构有Comodo、Symantec、GeoTrust、DigiCert、Thawte、GlobalSign、RapidSSL等;这其中的几家公司又属于DigiCert公司,如Symantec,GeoTrust,Thawte,RapidSSL
证书认证机制的流程
证书链和证书内容
访问网址时,浏览器会得到包含服务端证书的证书链,其用于在公钥基础设施中验证数字证书的有效性
上图是证书链的层次结构,证书链中最顶端的为根证书,根证书由浏览器内置,第二行为中间证书,第三行为用户证书(访问网址的证书)
仅当证书链上的每个证书均有效时,浏览器才会认定当前颁发给欲访问网址的证书是有效且受信任的
根证书:受信任的CA机构颁发给自己的证书,浏览器判断根证书是否受信任主要通过检索浏览器的根证书库的可信任列表
中间证书:根证书颁发机构CA对中间证书颁发机构的公钥进行数字签名得到的证书。中间证书的作用是为了保护根证书,若直接采用根证书签发证书,一旦根证书泄露,则会造成极大的安全问题,而中间证书可以不止有一个,原则上中间证书不会超过两级
用户证书:实际服务端申请所获得的证书
X.509标准定义了证书的内容
证书对应有两种编码格式:PEM和DER,PEM格式是base64编码,可以用文本程序代开,以-----BEGIN CERTIFICATE-----
开头,DER是二进制编码
openssl x509 -text -inform DER/PEM -in /xxx.cer(证书路径) # 打开指定格式的证书文件
openssl x509 -text -inform DER -in baidu.com.cer -out baidu.com.pem # 将DER转换为PEM格式
证书文件的后缀名:.crt,.cer,.pem,.der等,后缀名与编码格式并没有很大的关系
证书验证的流程
1、服务端申请证书:个人或组织首先生成密钥对,然后向CA机构提交证书请求(包括公钥和身份信息)
2、证书的颁发机构在验证服务端身份之后,对证书内容使用某种哈希算法生成摘要,然后使用机构自己的私钥加密摘要生成数字签名,然后将公钥、数字签名、使用的哈希算法、原证书内容合并在一起组成数字证书,发送给服务端
3、服务端作为申请方向每一个连接自己的客户端提供自己的数字证书
4、客户端收到数字证书后,使用数字证书中包含的公钥对数字证书中包含的数字签名进行解密得到摘要;然后再使用证书内的hash算法将证书内容进行hash之后得到新的摘要,将新的摘要和上一步得到的摘要进行对比,若相同则证明证书有效
5、依次取出第二级的证书使用上一级的公钥解密,按照上一步的方法验证摘要,一直到根证书
有效性验证
CA会提供一份证书失效名单,浏览器会缓存并定期更新该名单,且CA会提供实时接口查询
TLS协议概述
传输层安全协议,位于传输层与应用层之间,SSL是TLS的前身
协议层级架构
TCP协议之上,应用层协议之下
TLS协议内部分为两层:
- 下层为记录层协议:为TLS上层子协议的传送提供分片、消息加密、加密后的传输、对接收到的数据验证、解密、重新组装、将重新组装之后的数据传递给应用层
- 上层包含四种子协议:handshake protocol, alert protocol, application protocol, change cipher spec
协议流程概述
TLS的交互流程发生于TCP三次握手之后,典型的流程如下
- 客户端会发送ClientHello消息包,说明自己的TLS版本、支持的加密套件等信息;
- 服务端发送ServerHello消息包,确认选定的加密套件,是否支持压缩等信息,并在Certificate中添加自己的证书链信息;
- 客户端收到证书链后校验证书的有效性,随后生成主密钥,并将所需要的信息通过ClientKeyExchange发送给服务端(主密钥协商过程见密钥交换协议,并声明后续所有的消息都是加密后的内容(Change Cipher Spec);至此Client端已经完成协商,可以开始发送应用层数据;
- 服务端收到客户端的信息,生成主密钥,也声明后续的消息都为加密后的内容(Change Cipher Spec);
- TLS协商结束,开始加密传输应用层消息。
TLS协议数据包分析详解
Record Protocol
定义了数据的传输、分片、以及协商中的各种包类型
Handshake Protocol
在加密通信之前,对于加密使用的算法套件以及加密密钥进行协商
ContentType的定义主要有以下四种,每一种都是子协议:
- Handshake Protocal(22): 用于协商各种内容,例如加密套件等,常见的像ClientHello、ServerHello都属于这一类型;
- Change Cipher Spec Protocol(20):这个类型的消息只有一种子类型change_cipher_spec(1),用于宣告接下来的数据传输都使用协商后的加密方式进行,所以一般在加密信息协商完成之后发送,这包括重新协商的情况;
- Alert Protocol(21):用于表示警告或者错误的发生,包含有两个字段,AlertLevel(1)和AlertDescription(1)。需要注意的是,在TLS结束时,双方都需要发送close_notify类型的Alert来告诉对方已经传输完成;
- Application Data Protocol(23):携带需要传输的应用层数据。
client hello(客户端→服务端)
client hello包由客户端向服务端发送
重要参数详解
- Random:32字节的随机数,client hello包中的Random参数会和服务器端的Random参数合并,用来生成后续通信中使用的加密对称密钥。Random参数还可以用来识别和恢复TLS会话,若客户端和服务端之前已经建立过TLS会话,可以使用之前的会话标识来恢复会话,提高建立连接的效率
- Version:客户端期望交互的TLS的版本号,如TLS v1.2时,值为0x0303
- Session ID:标识和管理TLS会话,一个TLS会话可以包含多个TLS连接,Session ID允许客户端和服务器在建立新的TLS连接时恢复之前建立的会话,会话恢复过程中,客户端和服务器可以跳过一部分握手过程(密钥协商);在TLSv1.3中改为O-RTT
- Cipher Suites:客户端向服务器提供一组密钥交换算法、批量加密算法、消息认证码算法、伪随机算法函数 密钥协商算法:RSA、Diffie-Hellman
- Compression Methods:表明客户端支持的压缩算法,包括一个字节的长度信息和支持的压缩方法列表,列表中必须包含有null(0),表示支持不使用压缩
- 关于扩展,参见网站:HTTPS 温故知新(六) —— TLS 中的 Extensions
Server Hello(服务端→客户端)
回复ClinetHello,若客户端所有算法套件服务端不支持,则不会回复ServerHello,而会使用FailureAlert消息
参数详解:
Random:服务端也需要产生一个随机数来发送给客户端,客户端和服务端都需要使用这两个随机数来产生Master Secret
Version:确认使用的加密通信协议版本,若版本不一致,服务器会关闭加密通信
Cipher Suite:服务端支持的加密套件
Certificate(服务端→客户端)
服务端向客户端发送ServerHello后紧接着发送Certificate,内容包含证书链
Server Key Exchange(服务端→客户端)
服务端发送Certifacate之后发送Server Key Exchange
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 361
EC Diffie-Hellman Server Params
Curve Type: named_curve (0x03)
Named Curve: secp384r1 (0x0018)
Pubkey Length: 97
Pubkey: 04de89ab11412b76f9e1e62411a126bd3231abc407db7cbc27a35bedae71f41d9c916f69…
Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
Signature Length: 256
Signature: a46f336455c6d52abbafe11d1b0ab449ff329471851baede022fcce3944cd3e5e832d9a3…
Handshake Protocol: Server Hello Done
有关密钥协商算法ECDHE的参数传递,其中包括Curve Type--指明自己使用的椭圆曲线(ECDHE算法中的相关内容)。Signature Algorithm--服务器会使用自己的私钥对临时密钥交换算法中所涉及的参数进行加密生成数字签名,数字签名和参数会一并发送给客户端,客户端收到后要使用Pubkey解密以验证参数的确来自于服务器,加密算法就是Signature Algorithm中所涉及的算法。Pubkey--用来解密服务器用私钥加密的密钥交换算法参数。
以下是各个密钥交换算法所涉及的关键参数:
- RSA 密钥交换:
- 对于 RSA 密钥交换,服务器的关键材料包括:
- 服务器的 RSA 公钥。
- 一个随机生成的 Pre-Master Secret,它将在握手过程中与客户端的公钥协商得到共享的主密钥(Master Secret)。
- 对于 RSA 密钥交换,服务器的关键材料包括:
- Diffie-Hellman 密钥交换:
- 对于 Diffie-Hellman 密钥交换,服务器的关键材料包括:
- 服务器的 Diffie-Hellman 参数,包括大素数和生成元。
- 一个 Diffie-Hellman 公钥,通过使用服务器的私钥计算得出。
- 对于 Diffie-Hellman 密钥交换,服务器的关键材料包括:
- 椭圆曲线 Diffie-Hellman (ECDH) 密钥交换:
- 对于 ECDH 密钥交换,服务器的关键材料包括:
- 服务器的椭圆曲线参数,包括曲线类型和基点。
- 一个 ECDH 公钥,通过使用服务器的私钥计算得出。
- 对于 ECDH 密钥交换,服务器的关键材料包括:
Server Hello Done(服务端→客户端)
标识Server Hello消息的结束
Client Key Exchange(客户端→服务端)
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 98
EC Diffie-Hellman Client Params
Pubkey Length: 97
Pubkey: 044be475a0782e0c1e7ea872ed6f682b6e700ea1919016984e3d4007c4d6acab44ad8fbb…
在密钥交换算法中,客户端也需要给服务端发送一些关键参数,比如在ECDH算法中,客户端需要发送椭圆曲线公钥给服务端,还有一个客户端的随机数,这个随机数在client hello中已经发送给了服务端。
如果使用的是DH算法,此时客户端会使用Server Key Exchange中携带的DH公钥,生成一个pre-master key,然后将这个公钥放在Client Key Exchange包中发送给服务端,服务端会结合自己的私钥解出pre-master信息,得到第三个随机数,两边根据相关参数计算出会话密钥,之后使用会话密钥传递应用信息
Change Cipher Spec(客户端→服务端)
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
客户端通知服务端,自己已经准备好使用之前协商好的加密套件来加密后续的应用数据来进行通信了
Encrypted Handshake Message(客户端→服务端)
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message
在Change Cipher Spec传输完毕之后,客户端会使用之前协商好的加密套件加密一段数据传送给服务端,为了在正式传输应用数据之前对刚刚建立起来的加解密通道进行验证
New Session Ticket(服务端→客户端)
这是一个TLS扩展,允许服务器在握手完成后向客户端发送新会话的票据(Ticket)。这个Ticket包含了与该会话相关的信息,例如会话标识符、加密密钥等。客户端可以将这个Ticket存储起来,以便在未来的通信中重用,从而加快下一次通讯的连接建立速度。有助于提高性能和减少连接建立时的延迟。
Change Cipher Spec(服务端→客户端)
服务端通知客户端也准备好使用提前商量的加密套件来加密传送的应用数据了
Encrypted Handshake Message(服务端→客户端)
确认协商出来的会话密钥的正确性,本报文是使用会话密钥进行加密的第一个报文,若报文加解密成功,则说明对称密钥是正确的
无论是客户端还是服务端,都会在握手完成之后发送Encrypted handshake message,且各自收到对端的Encrypted handshake message后都会去验证这个数据
如何得到Encrypted handshake message:参考网址https://blog.csdn.net/mrpre/article/details/77868570
如果中间有人篡改了报文,比如,把客户端的client hello中提供的加密套件改成了一个弱秘钥算法,那么对于server而言,收到的client hello和客户端实际发送的不一样。假设server收到的叫做client_hello_bad,握手完后server在计算Encrypted handshake message时,因为使用了client_hello_bad,计算完成之后,会发送给客户端,客户端为了确定握手数据是否被篡改,也需要模拟server端计算这个Encrypted handshake message,显然客户端计算Encrypted handshake message 用的client hello 不是client_hello_bad,这样,客户端计算出来的,就和服务端发过来的不同了,验证失败
TLS和SSL的差异
- 版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
- 报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
- 伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
- 报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
- 密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。
- certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
- 加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
- 填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。
TLS协议的主要增强内容
- 更安全的MAC算法
- 更严密的警报
- “灰色区域”规范的更明确的定义
TLS对于安全性的改进
- 对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。
- 增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
- 改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
- 一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
- 特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。