tls加密套件
⑴ SSL握手分析及常见问题排查
1. 当要建立一个tls加密的连接时.客户端首先发送一个client hello消息给服务端,其中包含了一个客户端生成的随机数 random_1, 客户端支持的加密套件(support ciphers), 以及支持的tls版本等信息;
2. 服务端收到了客户端的请求时,会从client hello消息中取出随机数random_1, 客户端的加密套件等信息,确定使用哪一种加密套件,以及再生成一个随机数random_2, 并将这些信息包含在server hello消息中发送给客户端;然后服务端还会将自己的证书信息发送给客户端.
3. 客户端收到服务服务端的消息和证书后,会从中取出服务端生成的随机数random_2,以及确定的加密套件等信息.并将服务端下发的证书拿到自己系统里的CA列表中进行验证,验证合法后从证书中取出服务端的公钥, 再生成一个随机数random_3.并用服务端的公钥对random_3进行加密生成一个key发给服务端.
4. 服务端收到客户端发来的key之后,用自己的私钥对其解密,取出随机数random_3.
5. 至此,客户端和服务端都拥有了random_1, random_2, random_3三个随机数,以及确定了相同的加密套件.现在只要根据相同的加密算法对这三个随机数进行加密生成一个密钥,服务端和客户端就拥有了这个相同的密钥.此后的连接中,服务端和客户端都使用这个密钥对信息进行加密,就可以通过这种对称加密的方式进行密文传输了.
6. 我们可以发现,在服务端和客户端交换随机数的时候,是通过服务端向客户端下发公钥以非对称加密的形式完成的.当服务端和客户端都拿到了相同的三个随机数后,用这三个随机数生成了相同的密钥,此后的通信就是通过这个密钥加密和解密信息,实现了对称加密传输.
通常tls握手失败都是由服务端以及服务端tls配置问题导致的.
目前最主要的原因就是服务端的tls配置不支持ssl3.0.但是,客户端这边的问题也很有可能会导致的tls握手失败.比如,像系统时间不正确,或者浏览器更新所至等一些常见的客户端问题.
大部分情况下, tls握手失败都是由服务端问题所导致的. 其中有些问题很容易解决, 有些问题不容易解决,甚至有一些问题不值得去解决.
* 客户端支持tls1.0和tls1.1版本,但服务端只支持tls1.2
上面这个例子就是tls协议不匹配.但是,在这种情况下,要修复这个问题,不应该是服务端来匹配低版本的协议,而应该是客户端升级到tls1.2来匹配服务端较新的协议. 在目前,我们的建议是必须支持tls1.2和tls1.3协议,对于还不支持的网站必须添加上这两个版本.
tls/ssl并不是通过一个通过自身可以解决所有问题的算法,而是一系列不同算法的结合,不同的算法用以实现不同的功能,它们结合在一起组成了tls/ssl.
tls1.3版本的加密套件得到了进一步的完善.在这之前, 加密套件的算法主要包含以下功能:
* 对称密钥会话加密(Symmetric Session Key Encryption)
* 非对称公钥加密(Asymmetric Public Key Encryption)
* 证书签名哈希(Signature Hashing)
* 密钥生成(Key Generation)
许多原因都会导致浏览器判定tls证书不合法, 这时浏览器就会阻止tls握手连接. 在接下来的小节中, 我们会深入探讨由于此类技术问题所引发的tls握手失败问题.
* 域名不匹配: 网站域名与证书中的不相匹配.
* 证书链不正确: 证书链中缺少中间证书.
* 证书过期或被撤销: 服务端使用了不受信任, 过期, 或被撤销的tls证书.
* 使用自签名证书: 使用自签名证书或内部网络路径混乱
在以前,一个网站的非www域名和www域名之间存在着问题,但是后来证书颁发机构允许一个证书可以签发多个子域名(SAN),已经几乎解决了这个问题.处理证书域名错误的最好方法就是从新签发一个新证书,或者使用通配符证书.
SL/TLS和PKI信任模型通常依赖于根程序(Root program),这是存储在计算机系统上的受信任CA根证书的集合。其中一些根程序例如:
* 火狐浏览器使用的Mozilla根程序.
* 安卓系统使用的Google根程序.
* IOS和macOS系统所使用的Apple根程序.
* Windows系统使用的Microsoft根程序.
CA根程序十分重要,虽然它不直接签发证书,但证书机构会利用中间根证书来签发终端用户所使用的tls叶证书. 这就是证书链的运作方式, CA根证书被用来签发中间根, 中间根又用来签发其他中间根, 最终直到终端用户的tls叶证书.
当前,tls证书的最大有效期是2年. 因此,如果你的证书过期或者因为某些原因被注销了,将会导致tls握手失败的错误.解决方法是重新购买和安装一份合法的证书.
如果你的暴露在公网上的网站使用的是自签名证书,这是不被信任的,将会导致错误. 要解决这个错误,你需要去一个受信任的CA机构重新签署一份tls证书.
⑵ 网络(四):应用层HTTPS
网络(一):基础知识
网络(二):传输层TCP、UDP
网络(三):应用层HTTP
网络(四):应用层HTTPS
HTTPS(Hyper Text Transfer Protocol Secure),超文本传输安全协议,设计HTTPS的目的就是为了安全传输数据。HTTPS的默认端口号是443,HTTP的默认端口号是80。
HTTPS是安全的,但并非所有公司都使用了HTTPS,又或者公司某些涉及敏感数据的请求才使用了HTTPS、其它还是使用HTTP,这是因为使用HTTPS是有成本的:
HTTPS也常被称为HTTP over SSL或HTTP over TLS,即使用了SSL的HTTP或使用了TLS的HTTP。
TLS(Transport Layer Security),传输层安全协议,它的前身就是SSL(Secure Socket Layer),安全套接层协议。历史版本信息:
SSL/TLS工作在应用层和传输层之间,应用层的数据会使用SSL/TLS生成的密钥加密后再传递给传输层,从而保证了数据在传输过程中的安全性。
HTTPS的通信过程可以分为四大阶段:
接下来我们就看一下TLS是怎么生成和传输对称加密密钥的,这个过程会有十次关键的握手,我们省略了一些不关心的ACK:
客户端会给服务器发送一个 Client Hello 消息,该消息内部包含TLS的版本——用来告诉服务器客户端想使用哪个版本的TLS,包含支持的加密套件——用来告诉服务器客户端支持哪些密钥交换算法以及支持哪些加密算法、消息摘要算法,包含一个随机数Client Random——将来用来生成对称加密的密钥。
服务器会给客户端发送一个 Server Hello 消息,该消息内部包含TLS的版本——用来告诉客户端服务器想使用哪个版本的TLS,包含选择的加密套件——用来告诉客户端服务器选择了哪一套密钥交换算法以及哪一套加密算法、消息摘要算法(假设选择了TLS_ECDHE_ECDSA_...),包含一个随机数Server Random——将来用来生成对称加密的密钥。
服务器会给客户端发送一个 Certificate 消息—— 服务器会把在CA认证过的证书(包含公钥、公钥的数字签名等信息)发给客户端,客户端会用CA公钥来验证并获取到公钥,这个公钥就是将来非对称加密要用到的公钥。
服务器会给客户端发送一个 Server Key Exchange 消息—— 对称加密的密钥交换算法ECDHE_ECDSA需要一些参数,服务器需要提供一部分、并发给客户端,我们把服务器提供的这部分参数称之为Server Params。
服务器会给客户端发送一个 Server Hello Done 消息—— 服务器告诉客户端服务器已经没什么协商数据需要发给客户端了。
客户端会给服务器发送一个 Client Key Exchange 消息——对称加密的密钥交换算法ECDHE_ECDSA需要一些参数,客户端需要提供一部分、并发给服务器,我们把客户端提供的这部分参数称之为Client Params。
客户端会给服务器发送一个 Change Cipher Spec 消息——客户端告诉服务器以后客户端发给服务器的数据都会用对称加密的密钥进行加密。
客户端会给服务器发送一个 Finished 消息——客户端会把第一次TLS握手 ~ 第七次TLS握手全部的数据生成一个摘要,然后再把这个摘要用对称加密密钥1加密之后发送给服务器,目的就是为了让服务器去解密,进而判定对称加密密钥1能有效加解密。
服务器也会给客户端发送一个 Change Cipher Spec 消息——服务器告诉客户端以后服务器发给客户端的数据也都会用对称加密密钥2进行加密。
服务器会给客户端发送一个 Finished 消息——服务器会把第一次TLS握手 ~ 第九次TLS握手全部的数据生成一个摘要,然后再把这个摘要用对称加密密钥2加密之后发送给客户端,目的就是为了让客户端去解密,进而判定对称加密密钥2能有效加解密。
⑶ 前端安全
什么时候会跳过preflightrequest
Stored:存储
Reflected:反射性
DOM-based:未连接服务器
例子:
XSS防御:
标签白名单
转义(HTML + JavaScript)
禁止动态修改 CSS 资源引用
特殊协议(dataURI)
减少/避免一些 DOM 操作
CSP: 只允许从我认可的地方加载资源
验证码
Referer:请求头从哪个网站来的(HTTP Referer是header的一部分,当浏览器向web 服务器 发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。)
Anti CSRF Token:
尽量用 POST
DNS 劫持:
本地 host
设备(路由器/交换机)
DNS 服务器
HTTP劫持:
Man-in-the-middle attack(MITA)
防御 HTTP 劫持:
CSP
SRI
HTTPS
Browser:支持的 TLS 版本 + 加密套件,一个随机数1
Server:选择 TLS 版本 + 加密套件,一个随机数2,[session id]
[Server:证书(public key)]
[Server:ServerKeyExchange]
Server:over
Browser:验证证书,用证书中的 public key 加密新的随机数3,生成 PreMasterSecret
Browser + Server:使用 随机数1 + 随机数2 + PreMasterSecret,计算出 master secret,此后,所有信息都会用 master secret 加密
Browser:之前几步,涉及信息的 HASH + MAC,server 验证
Server:重复 browser 刚刚做的
⑷ TLS 详解
SSL (Secure Sockets Layer) 安全套接层,是一种安全协议,经历了 SSL 1.0、2.0、3.0 版本后发展成了标准安全协议 - TLS (Transport Layer Security) 传输层安全性协议。TLS 有 1.0 (RFC 2246)、1.1(RFC 4346)、1.2(RFC 5246)、1.3(RFC 8446) 版本。
TLS 在实现上分为 记录层 和 握手层 两层,其中握手层又含四个子协议: 握手协议 (handshake protocol)、更改加密规范协议 (change cipher spec protocol)、应用数据协议 (application data protocol) 和警告协议 (alert protocol)
只需配置浏览器和服务器相关设置开启 TLS,即可实现 HTTPS,TLS 高度解耦,可装可卸,与上层高级应用层协议相互协作又相互独立。
TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
TLS 的基本工作方式是,客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥,然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取。
例如,在 HTTPS 协议中,客户端发出请求,服务端会将公钥发给客户端,客户端验证过后生成一个密钥再用公钥加密后发送给服务端(非对称加密),双方会在 TLS 握手过程中生成一个协商密钥(对称密钥),成功后建立加密连接。通信过程中客户端将请求数据用协商密钥加密后发送,服务端也用协商密钥解密,响应也用相同的协商密钥。后续的通信使用对称加密是因为对称加解密快,而握手过程中非对称加密可以保证加密的有效性,但是过程复杂,计算量相对来说也大。
记录协议负责在传输连接上交换的所有底层消息,并且可以配置加密。每一条 TLS 记录以一个短标头开始。标头包含记录内容的类型 (或子协议)、协议版本和长度。原始消息经过分段 (或者合并)、压缩、添加认证码、加密转为 TLS 记录的数据部分。
记录层将信息块分割成携带 2^14 字节 (16KB) 或更小块的数据的 TLSPlaintext 记录。
记录协议传输由其他协议层提交给它的不透明数据缓冲区。如果缓冲区超过记录的长度限制(2^14),记录协议会将其切分成更小的片段。反过来也是可能的,属于同一个子协议的小缓冲区也可以组合成一个单独的记录。
压缩算法将 TLSPlaintext 结构转换为 TLSCompressed 结构。如果定义 CompressionMethod 为 null 表示不压缩
流加密(BulkCipherAlgorithm)将 TLSCompressed.fragment 结构转换为流 TLSCiphertext.fragment 结构
MAC 产生方法如下:
seq_num(记录的序列号)、hash(SecurityParameters.mac_algorithm 指定的哈希算法)
块加密(如 RC2 或 DES),将 TLSCompressed.fragment 结构转换为块 TLSCiphertext.fragment 结构
padding: 添加的填充将明文长度强制为块密码块长度的整数倍。填充可以是长达 255 字节的任何长度,只要满足 TLSCiphertext.length 是块长度的整数倍。长度大于需要的值可以阻止基于分析交换信息长度的协议攻击。填充数据向量中的每个 uint8 必须填入填充长度值 (即 padding_length)。
padding_length: 填充长度应该使得 GenericBlockCipher 结构的总大小是加密块长度的倍数。合法值范围从零到 255(含)。 该长度指定 padding_length 字段本身除外的填充字段的长度
加密块的数据长度(TLSCiphertext.length)是 TLSCompressed.length,CipherSpec.hash_size 和 padding_length 的总和加一
加密和 MAC 功能将 TLSCompressed 结构转换为 TLSCiphertext。记录的 MAC 还包括序列号,以便可以检测到丢失,额外或重复的消息。
记录协议需要一种算法,从握手协议提供的安全性参数生成密钥、 IV 和 MAC secret.
主密钥 (Master secret): 在连接中双方共享的一个 48 字节的密钥
客户随机数 (client random): 由客户端提供的 32 字节值
服务器随机数 (server random): 由服务器提供的 32 字节值
握手是 TLS 协议中最精密复杂的部分。在这个过程中,通信双方协商连接参数,并且完成身 份验证。根据使用的功能的不同,整个过程通常需要交换 6~10 条消息。根据配置和支持的协议扩展的不同,交换过程可能有许多变种。在使用中经常可以观察到以下三种流程:(1) 完整的握手, 对服务器进行身份验证;(2) 恢复之前的会话采用的简短握手;(3) 对客户端和服务器都进行身份验证的握手。
握手协议消息的标头信息包含消息类型(1 字节)和长度(3 字节),余下的信息则取决于消息类型:
每一个 TLS 连接都会以握手开始。如果客户端此前并未与服务器建立会话,那么双方会执行一次完整的握手流程来协商 TLS 会话。握手过程中,客户端和服务器将进行以下四个主要步骤:
下面介绍最常见的握手规则,一种不需要验证客户端身份但需要验证服务器身份的握手:
这条消息将客户端的功能和首选项传送给服务器。
是将服务器选择的连接参数传回客户端。
这个消息的结构与 ClientHello 类似,只是每个字段只包含一个选项,其中包含服务端的 random_S 参数 (用于后续的密钥协商)。服务器无需支持客户端支持的最佳版本。如果服务器不支持与客户端相同的版本,可以提供某个其他版本以期待客户端能够接受
图中的 Cipher Suite 是后续密钥协商和身份验证要用的加密套件,此处选择的密钥交换与签名算法是 ECDHE_RSA,对称加密算法是 AES-GCM,后面会讲到这个
还有一点默认情况下 TLS 压缩都是关闭的,因为 CRIME 攻击会利用 TLS 压缩恢复加密认证 cookie,实现会话劫持,而且一般配置 gzip 等内容压缩后再压缩 TLS 分片效益不大又额外占用资源,所以一般都关闭 TLS 压缩
典型的 Certificate 消息用于携带服务器 X.509 证书链 。
服务器必须保证它发送的证书与选择的算法套件一致。比方说,公钥算法与套件中使用的必须匹配。除此以外,一些密钥交换算法依赖嵌入证书的特定数据,而且要求证书必须以客户端支持的算法签名。所有这些都表明服务器需要配置多个证书(每个证书可能会配备不同的证书链)。
Certificate 消息是可选的,因为并非所有套件都使用身份验证,也并非所有身份验证方法都需要证书。更进一步说,虽然消息默认使用 X.509 证书,但是也可以携带其他形式的标志;一些套件就依赖 PGP 密钥
携带密钥交换需要的额外数据。ServerKeyExchange 是可选的,消息内容对于不同的协商算法套件会存在差异。部分场景下,比如使用 RSA 算法时,服务器不需要发送此消息。
ServerKeyExchange 仅在服务器证书消息(也就是上述 Certificate 消息)不包含足够的数据以允许客户端交换预主密钥(premaster secret)时才由服务器发送。
比如基于 DH 算法的握手过程中,需要单独发送一条 ServerKeyExchange 消息带上 DH 参数:
表明服务器已经将所有预计的握手消息发送完毕。在此之后,服务器会等待客户端发送消息。
客户端验证证书的合法性,如果验证通过才会进行后续通信,否则根据错误情况不同做出提示和操作,合法性验证内容包括如下:
由 PKI 体系 的内容可知,对端发来的证书签名是 CA 私钥加密的,接收到证书后,先读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后利用对应 CA 的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性;然后去查询证书的吊销情况等
合法性验证通过之后,客户端计算产生随机数字的预主密钥(Pre-master),并用证书公钥加密,发送给服务器并携带客户端为密钥交换提供的所有信息。这个消息受协商的密码套件的影响,内容随着不同的协商密码套件而不同。
此时客户端已经获取全部的计算协商密钥需要的信息: 两个明文随机数 random_C 和 random_S 与自己计算产生的 Pre-master,然后得到协商密钥(用于之后的消息加密)
图中使用的是 ECDHE 算法,ClientKeyExchange 传递的是 DH 算法的客户端参数,如果使用的是 RSA 算法则此处应该传递加密的预主密钥
通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信
Finished 消息意味着握手已经完成。消息内容将加密,以便双方可以安全地交换验证整个握手完整性所需的数据。
这个消息包含 verify_data 字段,它的值是握手过程中所有消息的散列值。这些消息在连接两端都按照各自所见的顺序排列,并以协商得到的主密钥 (enc_key) 计算散列。这个过程是通过一个伪随机函数(pseudorandom function,PRF)来完成的,这个函数可以生成任意数量的伪随机数据。
两端的计算方法一致,但会使用不同的标签(finished_label):客户端使用 client finished,而服务器则使用 server finished。
因为 Finished 消息是加密的,并且它们的完整性由协商 MAC 算法保证,所以主动网络攻击者不能改变握手消息并对 vertify_data 的值造假。在 TLS 1.2 版本中,Finished 消息的长度默认是 12 字节(96 位),并且允许密码套件使用更长的长度。在此之前的版本,除了 SSL 3 使用 36 字节的定长消息,其他版本都使用 12 字节的定长消息。
服务器用私钥解密加密的 Pre-master 数据,基于之前交换的两个明文随机数 random_C 和 random_S,同样计算得到协商密钥: enc_key = PRF(Pre_master, "master secret", random_C + random_S) ;
同样计算之前所有收发信息的 hash 值,然后用协商密钥解密客户端发送的 verify_data_C,验证消息正确性;
服务端验证通过之后,服务器同样发送 change_cipher_spec 以告知客户端后续的通信都采用协商的密钥与算法进行加密通信(图中多了一步 New Session Ticket,此为会话票证,会在会话恢复中解释);
服务器也结合所有当前的通信参数信息生成一段数据 (verify_data_S) 并采用协商密钥 session secret (enc_key) 与算法加密并发送到客户端;
客户端计算所有接收信息的 hash 值,并采用协商密钥解密 verify_data_S,验证服务器发送的数据和密钥,验证通过则握手完成;
开始使用协商密钥与算法进行加密通信。
HTTPS 通过 TLS 层和证书机制提供了内容加密、身份认证和数据完整性三大功能。加密过程中,需要用到非对称密钥交换和对称内容加密两大算法。
对称内容加密强度非常高,加解密速度也很快,只是无法安全地生成和保管密钥。在 TLS 协议中,最后的应用数据都是经过对称加密后传输的,传输中所使用的对称协商密钥(上文中的 enc_key),则是在握手阶段通过非对称密钥交换而来。常见的 AES-GCM、ChaCha20-Poly1305,都是对称加密算法。
非对称密钥交换能在不安全的数据通道中,产生只有通信双方才知道的对称加密密钥。目前最常用的密钥交换算法有 RSA 和 ECDHE。
RSA 历史悠久,支持度好,但不支持 完美前向安全 - PFS(Perfect Forward Secrecy) ;而 ECDHE 是使用了 ECC(椭圆曲线)的 DH(Diffie-Hellman)算法,计算速度快,且支持 PFS。
在 PKI 体系 一节中说明了仅有非对称密钥交换还是无法抵御 MITM 攻击的,所以需要引入了 PKI 体系的证书来进行身份验证,其中服务端非对称加密产生的公钥会放在证书中传给客户端。
在 RSA 密钥交换中,浏览器使用证书提供的 RSA 公钥加密相关信息,如果服务端能解密,意味着服务端拥有与公钥对应的私钥,同时也能算出对称加密所需密钥。密钥交换和服务端认证合并在一起。
在 ECDH 密钥交换中,服务端使用私钥 (RSA 或 ECDSA) 对相关信息进行签名,如果浏览器能用证书公钥验证签名,就说明服务端确实拥有对应私钥,从而完成了服务端认证。密钥交换则是各自发送 DH 参数完成的,密钥交换和服务端认证是完全分开的。
可用于 ECDHE 数字签名的算法主要有 RSA 和 ECDSA - 椭圆曲线数字签名算法 ,也就是目前密钥交换 + 签名有三种主流选择:
比如我的网站使用的加密套件是 ECDHE_RSA,可以看到数字签名算法是 sha256 哈希加 RSA 加密,在 PKI 体系 一节中讲了签名是服务器信息摘要的哈希值加密生成的
内置 ECDSA 公钥的证书一般被称之为 ECC 证书,内置 RSA 公钥的证书就是 RSA 证书。因为 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,所以 ECC 证书体积比 RSA 证书小,而且 ECC 运算速度更快,ECDHE 密钥交换 + ECDSA 数字签名是目前最好的加密套件
以上内容来自本文: 开始使用 ECC 证书
关于 ECC 证书的更多细节可见文档: ECC Cipher Suites for TLS - RFC4492
使用 RSA 进行密钥交换的握手过程与前面说明的基本一致,只是没有 ServerKeyExchange 消息,其中协商密钥涉及到三个参数 (客户端随机数 random_C、服务端随机数 random_S、预主密钥 Premaster secret),
其中前两个随机数和协商使用的算法是明文的很容易获取,最后一个 Premaster secret 会用服务器提供的公钥加密后传输给服务器 (密钥交换),如果这个预主密钥被截取并破解则协商密钥也可以被破解。
RSA 算法的细节见: wiki 和 RSA算法原理(二)- 阮一峰
RSA 的算法核心思想是利用了极大整数 因数分解 的计算复杂性
而使用 DH(Diffie-Hellman) 算法 进行密钥交换,双方只要交换各自的 DH 参数(在 ServerKeyExchange 发送 Server params,在 ClientKeyExchange 发送 Client params),不需要传递 Premaster secret,就可以各自算出这个预主密钥
DH 的握手过程如下,大致过程与 RSA 类似,图中只表达如何生成预主密钥:
服务器通过私钥将客户端随机数 random_C,服务端随机数 random_S,服务端 DH 参数 Server params 签名生成 signature,然后在 ServerKeyExchange 消息中发送服务端 DH 参数和该签名;
客户端收到后用服务器给的公钥解密验证签名,并在 ClientKeyExchange 消息中发送客户端 DH 参数 Client params;
服务端收到后,双方都有这两个参数,再各自使用这两个参数生成预主密钥 Premaster secret,之后的协商密钥等步骤与 RSA 基本一致。
关于 DH 算法如何生成预主密钥,推荐看下 Wiki 和 Ephemeral Diffie-Hellman handshake
其核心思想是利用了 离散对数问题 的计算复杂性
算法过程可以抽象成下图:
双方预先商定好了一对 P g 值 (公开的),而 Alice 有一个私密数 a(非公开,对应一个私钥),Bob 有一个私密数 b(非公开,对应一个私钥)
对于 Alice 和 Bob 来说通过对方发过来的公钥参数和自己手中的私钥可以得到最终相同的密钥
而第三方最多知道 P g A B,想得到私钥和最后的密钥很困难,当然前提是 a b P 足够大 (RFC3526 文档中有几个常用的大素数可供使用),否则暴力破解也有可能试出答案,至于 g 一般取个较小值就可以
如下几张图是实际 DH 握手发送的内容:
可以看到双方发给对方的参数中携带了一个公钥值,对应上述的 A 和 B
而且实际用的加密套件是 椭圆曲线 DH 密钥交换 (ECDH) ,利用由椭圆曲线加密建立公钥与私钥对可以更进一步加强 DH 的安全性,因为目前解决椭圆曲线离散对数问题要比因式分解困难的多,而且 ECC 使用的密钥长度比 RSA 密钥短得多(目前 RSA 密钥需要 2048 位以上才能保证安全,而 ECC 密钥 256 位就足够)
关于 椭圆曲线密码学 - ECC ,推荐看下 A Primer on Elliptic Curve Cryptography - 原文 - 译文
尽管可以选择对任意一端进行身份验证,但人们几乎都启用了对服务器的身份验证。如果服务器选择的套件不是匿名的,那么就需要在 Certificate 消息中跟上自己的证书。
相比之下,服务器通过发送 CertificateRequest 消息请求对客户端进行身份验证。消息中列出所有可接受的客户端证书。作为响应,客户端发送自己的 Certificate 消息(使用与服务器发送证书相同的格式),并附上证书。此后,客户端发送 CertificateVerify 消息,证明自己拥有对应的私钥。
只有已经过身份验证的服务器才被允许请求客户端身份验证。基于这个原因,这个选项也被称为相互身份验证(mutual authentication)。
在 ServerHello 的过程中发出,请求对客户端进行身份验证,并将其接受的证书的公钥和签名算法传送给客户端。
它也可以选择发送一份自己接受的证书颁发机构列表,这些机构都用其可分辨名称来表示:
在 ClientKeyExchange 的过程中发出,证明自己拥有的私钥与之前发送的客户端证书中的公钥匹配。消息中包含一条到这一步为止的所有握手消息的签名:
最初的会话恢复机制是,在一次完整协商的连接断开时,客户端和服务器都会将会话的安全参数保存一段时间。希望使用会话恢复的服务器为会话指定唯一的标识,称为会话 ID(Session ID)。服务器在 ServerHello 消息中将会话 ID 发回客户端。
希望恢复早先会话的客户端将适当的 Session ID 放入 ClientHello 消息,然后提交。服务器如果同意恢复会话,就将相同的 Session ID 放入 ServerHello 消息返回,接着使用之前协商的主密钥生成一套新的密钥,再切换到加密模式,发送 Finished 消息。
客户端收到会话已恢复的消息以后,也进行相同的操作。这样的结果是握手只需要一次网络往返。
Session ID 由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话 ID 以及协商的通信信息,占用服务器资源较多。
用来替代服务器会话缓存和恢复的方案是使用会话票证(Session ticket)。使用这种方式,除了所有的状态都保存在客户端(与 HTTP Cookie 的原理类似)之外,其消息流与服务器会话缓存是一样的。
其思想是服务器取出它的所有会话数据(状态)并进行加密 (密钥只有服务器知道),再以票证的方式发回客户端。在接下来的连接中,客户端恢复会话时在 ClientHello 的扩展字段 session_ticket 中携带加密信息将票证提交回服务器,由服务器检查票证的完整性,解密其内容,再使用其中的信息恢复会话。
这种方法有可能使扩展服务器集群更为简单,因为如果不使用这种方式,就需要在服务集群的各个节点之间同步会话。
Session ticket 需要服务器和客户端都支持,属于一个扩展字段,占用服务器资源很少。
⑸ SSL和TLS的区别
SSL和TLS都是加密协议,有网络请求的地方就可以使用这两种协议在传输层进行加密,确保数据传输的安全,SSL是TLS的前身,网景在1995年发布了直接发布了SSL 2.0版本,1.0版本没有对外发布。由于漏洞的原因,版本2.0也只是昙花一现,网景在1996年就发布了SSL3.0。随后在1999年的时候,基于SSL3.0版本,网景发布了TLS1.0版本(虽然TLS1.0在SSL3.0基础上的改动不太大,但是这些改动都是非常重要的)。
其实答案很显然,我们现在应该使用TLS协议,因为在2011年和2015年的时候SSL2.0和SSL3.0就已经分别被弃用了,而且由于漏洞的缘故,如果你的服务器配置了SSL的协议,还得手动将他们禁用掉。所以我们只给服务器配置TLS协议就好了,有的服务对TLS版本有要求,比如我最近在做的小程序开发,要求TLS版本最低2.0,所以你可以在 SSL Server Test 查看服务器的证书及协议等配置
为保证网络安全,我们需要给服务器颁发证书,这个证书可以自己生成,但是自己颁发证书是不安全的,可以被别人伪造,所以我们一般都是在第三方认证机构购买证书。那么问题来了,证书到底和协议是否有关联,我们是否需要区分SSL证书和TLS证书呢?答案是否定的,证书不依赖协议,和协议没有太大关联,我们也不需要去纠结是使用SSL证书和TLS证书,协议由服务器配置决定,证书是配合协议一块使用的。
关于证书可以参考知乎大神的回答 https://www.hu.com/question/52493697
本文参考:
https://www.globalsign.com/en/blog/ssl-vs-tls-difference/
⑹ 我们应该使用 TLS1.3 吗
SSL(Socket Layer Security)和 TLS(Transport Layer Security) 都是属于安全协议,主要作用是保证客户端和服务端之间能安全通讯。SSL是较早的协议,TLS 是 SSL的替代者。
SSL 版本 1.0、2.0 和 3.0,TLS 版本 1.0、1.2 和 1.3。SSL协议和TLS1.0 由于已过时被禁用,目前TLS 1.3 是互联网上部署最多的安全协议,它是TLS最新版本 ,它增强了过时的安全性,并增加了更多的触控性。通过下面几点可以有个简单认识:
现代浏览器支持 TLS 1.2 和 TLS 1.3 协议,但 1.3 版本要好得多。 TLS 1.3 对早期版本进行了多项改进,最明显的是简化了TLS握手操作,使得握手时间变短、网站性能得以提升、改善了用户体验,另外支持的密码套件更安全和简单。
密码套件
TLS/SSL 使用一种或多种密码套件。 密码套件是身份验证、加密和消息身份验证的算法组合。TLS 1.2 版使用的算法存在一些弱点和安全漏洞。在 TLS 1.3 中删除了这些算法:
另外一个很重要的更新是TLS1.3 支持 perfect-forward-secrecy (PFS)算法。
向前保密 (PFS)是特定密钥协商协议的一项功能,如果一个长周期的会话密钥被泄露,黑客就会截获大量数据,我们可以为每个会话生成唯一的会话密钥,单个会话密钥的泄露不会影响该会话之外的任何数据。
TLS在早期版本的握手期间可以使用两种机制之一交换密钥:静态 RSA密钥和 Diffie-Hellman 密钥。 在 TLS1.3 中,RSA 以及所有静态(非 PFS)密钥交换已被删除,只保留了DHE、ECDHE
可以查看网站的安全详情来确认它是否使用"ECDHE"或"DHE"。
AES (Advanced Encryption Standard) 对称加密,它是 高级加密 标准。早期的加密标准DES(Data Encryption Standard) 已被弃用。
AES选择合适的 加密模式 很重要,应用比较多的两种模式 CBC 和 GCM。
CBC 密码分组链接模式
明文分块,第一个块使用初始化向量,后面的每个明文块在加密前与前一个密文块进行异或运算。
这种模式存在的问题:
CTR 计数模式
明文分块按顺序编号,通过加密"计数器"的连续值来生成下一个密钥流块。CTR 模式非常适合在多核处理器上运行,明文块可以并行加密。
GCM 伽罗瓦/计数器模式
GCM = CTR + Authentication。其加密过程,明文块是按顺序编号的,然后这个块号与初始向量 组合并使用块密码E加密,然后将此加密的结果与明文进行异或以生成密文。
简单来说,GCM 是 CTR 身份验证的组合,它更快、更安全。它将接受流水线和并行化实现,并具有最小的计算延迟,所以它的应用更加广泛。
客户端最低版本
客户端最低版本
一般建议同时兼容1.2和1.3
测试是否支持 TLS 1.2
测试是否支持 TLS 1.3
⑺ 什么是SSL/TLS解密
SSL加密是在传输层对网络连接进行加密,安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。就是我们看到地址栏https://,TLS加密套件、SSL属于数字证书,相互相成。
起初是因为HTTP在传输数据时使用的是明文(虽然说POST提交的数据时放在报体里看不到的,但是还是可以通过抓包工具窃取到)是不安全的,为了解决这一隐患网景公司推出了SSL安全套接字协议层,SSL是基于HTTP之下TCP之上的一个协议层,是基于HTTP标准并对TCP传输数据时进行加密,所以HTTPS是HTTP+SSL/TCP的简称。
⑻ TLS加密过程
## SSL 证书类型
**certbot**
域名验证(domain validated, DV证书)
组织验证(organization validated,OV 证书):验证组织是否正确
扩展验证(extended validation EV证书):显示友好
根证书-》二级证书-》主站点
## TLS加密过程
1. 验证身份
2. 达成安全套件共识
3. 传递密钥
4. 加密通讯
HTTPS采用混合加密算法,即共享秘钥加密(对称加密)和公开秘钥加密(非对称加密)。
通信前准备工作:
A、数字证书认证机构的公开秘钥(CA公钥)已事先植入到浏览器里;
B、数字证书认证机构用自己的私有密钥对服务器的公开秘钥做数字签名,生成公钥证书,并颁发给服务器。
1、client hello
握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。
2、server hello
服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。
3、Certificate
这一步是服务端将自己的公钥证书下发给客户端。
4、Server Hello Done
Server Hello Done 通知客户端 Server Hello 过程结束。
5、Certificate Verify
客户端收到服务端传来的公钥证书后,先从 CA 验证该证书的合法性(CA公钥去解密公钥证书),验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3生成 PreMaster Key。
6、Client Key Exchange
上面客户端根据服务器传来的公钥生成了 PreMaster Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。
为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被破解出来。
⑼ TLS过程(DH 非对称加密)
TLS 的目的便是解决数据的
一、Record 记录协议 (对称加解密)
二、HandShake 握手,挥手
验证通讯双方身份
交换加解密的安全套件
协商加密解密参数
当一个TLS会话建立好之后,会使用对称加密的密钥去通信,那么如何实现事先将对称加密的密钥传递给TLS会话的另一方呢。利用的就是非对称加密。分对称加密比对称加密慢数千倍,所以只是使用对称加密传递之后加密使用的对称加密的密钥。之后的加密安全性靠的是对称加密来解决。
非对称加密是有一把公钥和一把私钥,公钥可以公开,而私钥不能。
用公钥加密成密文,再将密文用私钥解密就能实现加解密过程。
而用私钥加密,公钥解密就是签名认证过程。
常见的非对称加密方式分为两大类
RSA 没有向前安全性,也就是需要每次的对称加密密钥的传递都是基于 公钥加密,服务端私钥解密。如果服务端的私钥丢失了,那几年前的通信数据都有可能被解密。所以这是极度不安全的,私钥的地位太重了,如果每次的加解密都是临时生成的密码来解决安全性,才不会对私钥的安全性有如此强的依赖。在2013年的棱镜门事件中,某个CA机构迫于美国政府压力向其提交了CA的私钥,这就是十分危险的。如果向前不安全,那么之前利用该CA私钥都会全部遭殃。所以这里说的是更安全的 DH类非对称加密。
下图就是DH密钥交换的TLS握手过程
DH 密钥交换协议,Diffile-Hellman key Exchange,简称 DH 或 DHE 。它可以让双方在完全没有对方任何预先信息的条件下通过一个不安全的信道创建一个密钥。
1、客户端浏览器随机生成一个值Ra,计算Pa(x,y) = Ra*Q(x,y), Q(x,y)为全世界公认的某个椭圆曲线算法的基点。将Pa(x,y)发送至服务器。
2、服务器随机生成一个值Rb,计算 Pb(x,y) = Rb * Q(x,y)。将Pb(x,y)发送到客户端浏览器。
3、客户端计算Sa(x,y) = Ra * Pb(x,y),服务器计算Sb(x,y)=Rb*Pa(x,y)
4、算法保证了Sa=Sb=S, 提取其中的S的x向量作为密钥。
为了解决上述DH的问题,引入了ECC椭圆曲线,进而进化为 ECDHE 算法,称为 Elliptic Curve Diffie-Hellman Key Exchange。ECC和RSA 在288字节的长度下,破解RSA需要煮沸一勺水的能量,而破解相同位数的ECC 就需要煮沸整个地球水的能量。RSA 为了提高安全性,只能靠增大密钥位数。尴尬的是现在的超算越来越厉害。量子计算下秀尔算法可8h内轻松破解2048位的RSA。RSA只能再增大密钥位数,但是再增大位数,移动端设备就惨了,你增大的密钥是运营商要收取流量费用的,而且加解密太费电。
ECC 的数学原理是椭圆曲线和离散对数。椭圆曲线很复杂。为了提升性能,还需要选择一个椭圆曲线,但是它不是真正的椭圆形,下面有图可以看到,只是运算上用到了椭圆算法。
但是ECC也有很多问题,1、ECC 可能有后门,如NSA(美国国家安全局发布的一套算法),这个算法就是被怀疑被植入后门了。2、而且ECC很多的算法都被注册专利了,一不小心就要吃官司,其专利大部分都被黑莓注册。
ECC 椭圆曲线的定义
ECC 的算法原理过于复杂,这里表示我也看不懂。点到为止吧。(以后看懂了再来补充)
这里的抓包结果就是用的EC DH E 算法来进行密钥交换的。这里选择的曲线是 secp256r1, 在这个曲线中,基点和参数已经给出了,PubKey 也给出了。
在 TLS1.3 中,一般使用的 X25519 曲线 (蒙哥马利曲线)
⑽ 用WireShark简单看看SSL/TLS协议
HTTPS目前是网站标配,否则浏览器会提示链接不安全,同HTTP相比比,HTTPS提供安全通信,具体原因是多了个“S”层,或者说SSL层[Secure Sockets Layer],现在一般都是TLS[Transport Layer Security],它是HTTP 明文 通信变成安全 加密通信 的基础,SSL/TLS介于应用层和TCP层之间,从应用层数据进行加密再传输。安全的核心就在加密上:
如上图所示,HTTP明文通信经中间路由最终发送给对方,如果中间某个路由节点抓取了数据,就可以直接看到通信内容,甚至可以篡改后,路由给目标对象,如下:
可见HTTP传输是不安全的,但,如果传输的是只有双方可校验的密文,就可以避免被偷窃、篡改,保证传输的安全性,这就是SSL/TLS层做的事情。
SSL/TLS协议主要从三方面来保证数据传输的安全性:保密、鉴别、完整:
对用户端而言:怎么保证访问的网站就是目标网站?答案就是 证书 。每个HTTPS网站都需要TLS证书,在数据传输开始前,服务端先将证书下发到用户端,由用户根据证书判断是否是目标网站。这其中的原理是什么,证书又是如何标识网站的有效性呢?证书也叫 digital certificate 或者public key certificate,是密码学中的概念,在TLS中就是指CA证书【 由证书的签发机构(Certificate Authority,简称为 CA)颁布的证书 】,好比是权威部门的公章,WIKI网络解释如下:
大意就是证书包含了目标站点的身份信息,并可以通过某种方式校验其合法性,对于任何一个HTTPS网站,你都可以拿到其CA证书公钥信息,在Chrome浏览器中点击HTTPS网站的锁标志,就可以查看公钥信息,并可以导出CA二进制文件:
浏览器就是通过这个文件来校验网站是否安全合法,可以看到,证书其实内置了一个颁发链条关系,根证书机构->次级证书机构->次次级->网站自身,只要验证这个链条是安全的,就证明网站合法,背后的技术其实是 信任链+RSA的非对称加密+系统内置根证书 。CA在颁发证书的时候,会用自己的私钥计算出要颁发证书的签名,其公钥是公开的,只要签名可被公钥验证就说明该证书是由该CA颁发的,核心校验逻辑如下
那么上级的CA又是如何保证安全呢?重复上述操作即可,最终都是靠根证书来验证的,根证书的安全性不需要验证,由系统保证,如此就形成了一个证书的信任链,也就能验证当前网站证书的有效性,证书的信任链校验如下:
TLS协议最大的提升点就是数据的安全,通HTTP通信相比,HTTPS的通信是加密的,在协商阶段,通过非对称加密确定对称加密使用的秘钥,之后利用对称秘钥进行加密通信,这样传输的数据就是密文,就算中间节点泄漏,也可以保证数据不被窃取,从而保证通信数据的安全性。
第三个问题,虽然中间节点无法窃取数据,但是还是可以随意更改数据的,那么怎么保证数据的完整性呢,这个其实任何数据传输中都会有这个问题,通过MAC[Message Authentication Codes]信息摘要算法就可以解决这个问题,同普通MD5、SHA等对比,MAC消息的散列加入了秘钥的概念,更加安全,是MD5和SHA算法的升级版,可以认为TLS完整性是数据保密性延伸,接下来就借助WireShark看看TLS握手的过程,并看看是如何实现身份鉴别、保密性、完整性的。
HTTPS安全通信简化来说: 在协商阶段用非对称加密协商好通信的对称秘钥 ,然后 用对称秘钥加密进行数据通信 ,简易的WireShark TLS/SSL协商过程示意如下:
细化分离后示意如下:
握手分多个阶段,不过一次握手可以完成多个动作,而且也并不是所有类型的握手都是上述模型,因为协商对称秘钥的算法不止一种,所以握手的具体操作也并非一成不变,比如RSA就比ECDHE要简单的多,目前主流使用的都是ECDHE,具体流程拆分如下:
Client Hello是TLS/SSL握手发起的第一个动作,类似TCP的SYN,Client Hello 阶段客户端会指定版本,随机数、支持的密码套件供服务端选择,具体的包数据如下
启动TLS握手过程, 提供自己所能支持各种算法,同时提供一个将来所能用到的随机数 。
ContentType指示TLS通信处于哪个阶段阶段,值22代表Handshake,握手阶段,Version是TLS的版本1.2,在握手阶段,后面链接的就是握手协议,这里是Client Hello,值是1,同时还会创建一个随机数random给Server,它会在生成session key【对称密钥】时使用。之后就是支持的供服务端选择的密码套件,接下来等服务端返回。
Handshake Type: Server Hello (2),作为对Client Hello的响应 , 确定使用的加密套件 : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f),密钥协商使用 ECDHE,签名使用 RSA,
数据通信通信使用 AES 对称加密,并且密钥长度是128位,GCM分组,同时生成一个服务端的random及会话ID回传。
这一步服务器将配置的证书【链】发送给客户端,客户端基于上文所述的证书链校验证书的有效性,这里发送的证书是二进制格,可以利用wireshark右键“Export Packet Bytes”功能,导出.CER格式的证书。如下可以看到传输的证书链。
导出的CER格式的证书如下,最关键的就其公钥跟数字签名。
Server Key Exchange是针对选定的ECDHE协商所必须的步骤,Diffie-Hellman模型解释如下:
大意就是ephemeral Diffie-Hellman不会使用证书中的静态公钥参与对称秘钥的生成,而是需要服务端与客户端通过彼此协商确定对称秘钥,而D-H算法模型需要两对非对称秘钥对,各端保留自己的私钥,同时握有双方的公钥,然后基于D-H算法双端可以算出一样的对称加密秘钥,而这就需要C/S互传自己的公钥
服务端做完这一步,其实ECDHE算法中服务端需要提供的信息已经结束,发送 Server Hello Done告诉客户端,然后等待客户端回传它的D-H公钥。
算法:
其中p和g是公开的DH参数,只要P是一个足够大的数,在不知道私钥的情况下,即使截获了双方的公钥,也是很难破解的。
客户端收到服务端的证书后,利用信任链检测证书有效性,同时也会同Server Key Exchange 类似,将自己的Diffie-Hellman公钥发送给Server端,
至此,ECDHE协商所需要的信息都传输完毕, 双方都可以基于ECDHE算法算出的共享密钥,同时结合之前的随机数生成最终的对称加密秘钥:
之后客户端发送Change Cipher Spec与 Encrypted Handshake Message标识握手完成,同时传输一个加密的数据给Server,验证双方确立的秘钥是否正确,这就需要服务端也要重复这个操作给客户端,这样才能验证彼此的加解密一致,即服务端也要来一次Encrypted Handshake Message回传给客户端校验,
走完如上流程,双方就确认了正确的对称加密通道,后面就是TLS的数据通信,其Record Layer的ContentType 也会变成 Content Type: Application Data (23):
最终对称会话密钥包含三部分因子:
Client Hello与Server Hello阶段交换的随机数,是为了提高秘钥的“随机”程度而进行的,这样有助于提高会话密钥破解难度。
HTTPS通过加密与完整性校验可以防止数据包破解与篡改,但对于主动授信的抓包操作是没法防护,比如Charles抓包,在这个场景用户已经风险,并且将Charles提供的证书信任为根证书,这从源头上构建了一条虚拟的信任链:在握手阶段,Charles利用自己的公钥,生成客户端可以信任的篡改证书,从而可以充作中间人进而抓包,所谓中间人攻击,感觉跟Https抓包原理一样,都是要强制添加一个自己的信任根证书。