精华内容
下载资源
问答
  • tls 握手
    千次阅读
    2021-08-24 15:48:40

    https://segmentfault.com/a/1190000021559557

    此文主要内容翻译至博客How to Fix the SSL/TLS Handshake Failed Error?,并做了一些添加,修改和删除.

    当浏览器向web服务器(如Apache)发送一个安全的请求时,ssl/tls握手过程就开始了.ssl/tls错误时有发生,其中最常见的错误就是SSL Handshake Failed error.下面我们就来讲解什么是SSL/TLS握手失败,以及如何解决.

    SSL/TLS握手过程简述

    在讲述tls握手失败问题之前,有必要先简述一下tls握手过程:

    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握手失败的原因有很多.只要客户端和服务端的握手过程中的某一个环节出了问题,都有可能导致tls握手失败.下面概括出现tls握手失败的一些常见问题.

    原因描述哪里修复
    系统时间不准确客户端的日期或时间不准确客户端
    浏览器错误浏览器设置导致的错误客户端
    中间人连接被第三方操控或劫持客户端
    协议不匹配服务端不支持客户端所使用的协议服务端
    加密套件不匹配服务端不支持客户端使用的加密套件服务端
    服务端启用了服务器名称指示(SNI-Enabled)由于启用了SNI导致服务端无法与客户端完成通信服务端
    证书错误<ul><li>证书中的域名与url中的域名不符</li><li>证书链不完整或错误</li><li>tls证书过期或被撤销</li></ul>服务端

    下面,我们来详细的了解一下为何以上原因会导致tls握手失败,以及如何解决.

    由客户端带来的问题以及解决方案

    通常tls握手失败都是由服务端以及服务端tls配置问题导致的.
    目前最主要的原因就是服务端的tls配置不支持ssl3.0.但是,客户端这边的问题也很有可能会导致的tls握手失败.比如,像系统时间不正确,或者浏览器更新所至等一些常见的客户端问题.
    下面来详细解释一些常见的客户端问题.

    1. 系统时间错误

    这种情况通常不会发生,但有时系统时间会与真实时间不符.
    原因是tls认证是有一个特定的有效期的,所以错误的系统时间可能会导致tls握手失败.
    如果握手失败是由系统时间显示不正确导致,解决方法就是修正计算机的系统时间.

    2. 浏览器错误

    浏览器(客户端)的某些错误可能导致tls握手失败.例如浏览器某些设置错误,或由某些插件导致等原因,都有可能导致你访问合法网站时发生错误.但是定位和修复浏览器问题是非常困难的,最简单的方法是切换到其他浏览器来访问.
    如果切换到其他浏览器还是tls握手失败,那么问题就不是由浏览器本身导致的.但还是有可能是由一些插件导致的,排查一下你的系统里装了哪些可以影响多个浏览器的插件,将它们关闭后,将浏览器恢复默认设置并重启.如果还有问题,那就可能是其他原因导致的.

    3. 中间人

    通常,中间人劫持是一种试图损害或窃取用户信息的犯罪活动.但也不完全是这种情况.处于检查或做负载均衡等原因,许多程序和设备也会先截取信息再将其发送到服务端,这也被称为中间人.

    这些中间人设备有时也会导致tls握手失败.原因可能是网络防火墙阻止了连接,或是服务端网络的其他边缘设备的设置导致的.在这种情景下,导致错误的原因既可能来源于客户端,也可能来源于服务端.

    如果问题来源于客户端,你可以通过调整自己系统VPN,防毒软件和防火墙的设置来打通连接.
    如果问题是由服务端导致的,那大部分是由于网络中的边缘设备配置所造成的问题.

    服务端导致的问题及解决方案

    大部分情况下, tls握手失败都是由服务端问题所导致的. 其中有些问题很容易解决, 有些问题不容易解决,甚至有一些问题不值得去解决.
    下面来看看一些常见的服务端问题.

    1. 协议不匹配

    这是一个在服务端和客户端都可能出现的错误, 需根据实际情况来判断是否要去解决这个问题. 而且当问题是出现在加密或协议相关时,建议的解决方法是更新到新的版本, 而不是回退到旧版本.

    例如:  

    虽然tls1.2已经诞生十多年了,但仍有一小部分网站还不支持. 而且早在2018年3月, tls1.3的最终版本就在RFC 8446 by the IETF上发版了,并建议所有网站添加对tls1.3版本的支持.

    所以, 如果tls握手失败的原因是协议不匹配,那通常原因是服务端和客户端支持的tls版本不同.

    例如:

    • 客户端支持tls1.0和tls1.1版本,但服务端只支持tls1.2

    上面这个例子就是tls协议不匹配.但是,在这种情况下,要修复这个问题,不应该是服务端来匹配低版本的协议,而应该是客户端升级到tls1.2来匹配服务端较新的协议. 在目前,我们的建议是必须支持tls1.2和tls1.3协议,对于还不支持的网站必须添加上这两个版本.

    2. 加密套件不匹配

    tls/ssl并不是通过一个通过自身可以解决所有问题的算法,而是一系列不同算法的结合,不同的算法用以实现不同的功能,它们结合在一起组成了tls/ssl.

    tls1.3版本的加密套件得到了进一步的完善.在这之前, 加密套件的算法主要包含以下功能:

    • 对称密钥会话加密(Symmetric Session Key Encryption)
    • 非对称公钥加密(Asymmetric Public Key Encryption)
    • 证书签名哈希(Signature Hashing)
    • 密钥生成(Key Generation)

    不同组织和机构有不同的加密标准, 支持不同的加密套件.所以为了匹配服务端, 客户端必须提供多种加密套件的支持. 同样,一般服务端也会支持多种加密套件.

    在网络连接中经常会发生这种情况, 你尝试和服务端建立一个tls连接, 在客户端和服务端之间存在一个边缘设备(如负载均衡, 反向代理等), 这个边缘设备接收并解密了你的https流量,再重新加密发送到在他之后的服务端. 但如果这个边缘设备和服务端之间的加密套件不匹配, 就会导致错误. 同协议版本不匹配类似, 加密套件不匹配时, 通常是采取升级而不是降级来解决问题.

    最后强调一点, 被弃用的协议版本或密码套件通常是因为他们存在安全隐患. 所以,如果你采取降级来解决此类问题将会降低https连接的安全性.

    3. tls/ssl证书错误

    许多原因都会导致浏览器判定tls证书不合法, 这时浏览器就会阻止tls握手连接. 在接下来的小节中, 我们会深入探讨由于此类技术问题所引发的tls握手失败问题.

    • 域名不匹配: 网站域名与证书中的不相匹配.
    • 证书链不正确: 证书链中缺少中间证书.
    • 证书过期或被撤销: 服务端使用了不受信任, 过期, 或被撤销的tls证书.
    • 使用自签名证书: 使用自签名证书或内部网络路径混乱

    4. 域名错误

    在以前,一个网站的非www域名和www域名之间存在着问题,但是后来证书颁发机构允许一个证书可以签发多个子域名(SAN),已经几乎解决了这个问题.处理证书域名错误的最好方法就是从新签发一个新证书,或者使用通配符证书.

    5.证书链不正确

    SSL/TLS和PKI信任模型通常依赖于根程序(Root program),这是存储在计算机系统上的受信任CA根证书的集合。其中一些根程序例如:

    • 火狐浏览器使用的Mozilla根程序.
    • 安卓系统使用的Google根程序.
    • IOS和macOS系统所使用的Apple根程序.
    • Windows系统使用的Microsoft根程序.

    CA根程序十分重要,虽然它不直接签发证书,但证书机构会利用中间根证书来签发终端用户所使用的tls叶证书. 这就是证书链的运作方式, CA根证书被用来签发中间根, 中间根又用来签发其他中间根, 最终直到终端用户的tls叶证书.

    无论什么时候,只要浏览器收到了张tls证书,都会去去检查它签名的真实性. 在签发该证书的中间根中验证它的数字签名,然后再将该中间根的数字签名拿到签发它的中间根上去验证,如此层层递进,最终会追溯到一个受信任的CA根证书.

    因此,无论处于什么原因导致这个检验过程不能完整的进行,甚至浏览器只是不能定位其中一个中间根,都会导致tls握手失败的错误.
    解决方案是安装缺失了的中间证书.缺失的中间证书可以在你购买tls证书的CA机构网站找到.

    6. 证书过期或被注销

    当前,tls证书的最大有效期是2年. 因此,如果你的证书过期或者因为某些原因被注销了,将会导致tls握手失败的错误.解决方法是重新购买和安装一份合法的证书.

    7. 使用自签名证书

    如果你的暴露在公网上的网站使用的是自签名证书,这是不被信任的,将会导致错误. 要解决这个错误,你需要去一个受信任的CA机构重新签署一份tls证书.

    8. 开启了服务器名称标识(SNI-Enabled)

    通常,这是一个发生在服务端设备之间的内部问题,但有时一个未开启SNI的客户端去访问一个开启了SNI的服务端,就可能发生tls握手错误.

    要解决这个问题,你必须确定服务器的主机名和端口号,同时还要验证服务器是否开启了SNI验证,以及验证服务器是否传递了所有的必要信息.

    总结

    通常网站管理者不需要做任何改变, 但如果一旦遇到了此类问题,绝对不能忽视. 尽管有时问题是由客户端导致的, 但正如此文中提到的一样,其中大多数情况都是有服务端导致的.

    所以,如果你只是一个普通的用户,你能做的事情是有限的. 最好的方法就是将问题上报给网站管理员,等待他们来修复.

    更多相关内容
  • 第一部分:介绍TLS握手协议内容。(非常粗略的介绍,详见《图解密码技术》-- 结城浩 – 第14章 SSL/TLS 为了更安全的通信) 第二部分:安装wireshark,使用其进行抓数据包,为后面TLS分析做准备。 第三步:详细查看...

    摘要

    程序员干活可以分为三步:明确目标-需求;了解需求的背景知识;调用API实现目标。

    第一部分:介绍TLS握手协议内容。(非常粗略的介绍,详见《图解密码技术》-- 结城浩 – 第14章 SSL/TLS 为了更安全的通信)

    第二部分:安装wireshark,使用其进行抓数据包,为后面TLS分析做准备。

    第三步:详细查看TLS握手的每一步。最后使用一个示例验证握手过程的掌握情况。

    第四步:调用ssl - OpenSSL SSL/TLS library,实现一个客户端连接。


    TLS握手协议介绍

    本节来源:《图解密码技术》-- 结城浩 – 第14章 SSL/TLS 为了更安全的通信

    TLS 协议 是由 TLS 记录协议 ( TLS record protocol) 和 TLS 握 手协议 ( TLS handshake protocol) 这两层协议叠加而成的。

    TLS 握手协议分为下列 4 个子协议 : 握手协议、密码规格变更协议、警告协议和应用数据协议。

    在这里插入图片描述

    握手协议是 TLS 握手协议的一部分,负责生成共享密钥以及交换证书 。 其中,生成共享密钥是为了进行密码通信,交换证书是为了通信双方相互进行认证。

    握手协议的过程如下图所示 。

    在这里插入图片描述

    下一节,我们通过抓包,验证这张图片中的握手过程。


    准备工作

    安装wireshark

    参考:Ubuntu 上 Wireshark 的安装与使用

    sudo apt install wireshark # 选择yes,表允许非超级用户捕获数据包
    sudo usermod -aG wireshark $(whoami)
    reboot
    

    wireshark的使用

    参考:wireShark的基本用法

    我的抓包需求:

    • 抓取的内容流进enp2s0接口。
    • 抓取dstsrcwww.baidu.com的内容。

    所以,wireshark输入设置如下。

    在这里插入图片描述

    我们使用openssl-s_client,作为客户端程序。(不使用浏览器是避免一些不必要的干扰)

    openssl s_client -connect www.baidu.com:443
    

    wireshark抓取内容如下:

    在这里插入图片描述


    看见TLS握手过程

    (0)TCP的三次握手

    前三个数据包是TCP的三次握手过程,感兴趣的话,可以阅读实战!我用 Wireshark 让你“看见“ TCP

    (1)Client Hello (客户端–>服务器)

    在这里插入图片描述

    其中的密码套件,拉出来,单独介绍下。

    密码套件含义 :SSL/TLS 提供了 一种密码通信的框架,这意味着 SSL/TLS 中使用的对称密码、公钥密码 、数字签名、单向散列函数等技术,都是可以像零件一样进行替换的 。 也就是说,如果发现现在所使用的某个密码技术存在弱点,那么只要将这一部分进行替换就可以了 。尽管如此,也并不是说所有的组件都可以自由选择 。 由千实际进行对话的客户端和服务器必须使用相同的密码技术才能进行通信,因此如果选择过于自由,就难以确保整体的兼容性 。为此, SSL/TLS 就像事先搭配好的盒饭一样,规定了 一些密码技术的“推荐套餐",这种推荐套餐称为密码套件 (cipher suite)。(来源:《图解密码技术》14.2.6)

    密码套件-wiki中的参考链接7–TLS/SSL (Schannel SSP) 中的密码套件,内容不错,我搬运下。

    密码套件是一组加密算法。 TLS/SSL 协议的 schannel SSP 实现使用密码套件中的算法来创建密钥和加密信息。 密码套件为以下每种任务指定一种算法:

    • 密钥交换算法:保护创建共享密钥所需的信息。这些算法是非对称的,并且对于相对较少的数据性能良好。
    • 批量加密算法:对客户端和服务器之间交换的消息进行加密。 这些算法是对称的,适用于大量数据。
    • 消息验证算法:生成消息哈希和签名,以确保消息的完整性。

    开发人员通过使用ALG_ID数据类型来指定这些元素。

    密码套件名称结构,如下图所示。

    在这里插入图片描述

    可以看到TLS_AES_256_GCM_SHA384套件,不符合密码套件的名称结构。参考TLS-mozilla,推测没有密钥交换算法,可能表示密钥交换算法可以任意。这样的好处是,避免有太多的密码套件名称。

    至于每个套件的具体含义,我不知道到。遇到一个查一个呗。

    (2) Server Hello (客户端<–服务器)

    服务器给客户端发送的内容:使用的版本号,当前时间,服务器随机数,会话 ID,使用的密码套件,使用的压缩方式

    在这里插入图片描述

    新建立的会话,Session id length是0。参考SSL_get_session,当session还存在时,ssl 会话包含重新建立连接所需的所有信息,无需完全握手。(有点类似与web中的session)

    我们来看下TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256密码套件:

    • TLS:Transport Layer Security 协议

    • ECDHE:Elliptic Curve Diffie-Hellman Ephemeral 密钥交换算法。关于Diffie-Hellman,可以参考《图解密码技术》11.5。使用这种算法,通信双方仅通过交换一些可以公开的信息就能够生成出共享的秘密数字,而这一秘密数字就可以被用作对称密码的密钥 。 (这里用于计算预主密钥)

      注:下图是DHE算法,ECDHE是它的改进版。但两者的输入和输出应该是一样的。这里贴下DHE算法的示意图。

      在这里插入图片描述

    • RSA:签名使用的非对称算法。对两个hello的随机数和服务端(或客户端)的DH随机数,进行签名。表明自己拥有对应证书的私钥。(RSA是在下方使用的,签名过程也在下方)

    • AES_128_GCM:对称加密,加密消息流。GCM可以提供对消息的加密和完整性校验。

    • SHA256:计算消息认证码(Message Authentication Code,MAC)。计算位置应该是下图位置。

      在这里插入图片描述

    接下来的Certificate, Server Key Exchange, Server Hello Done在一个数据包中,从服务端发送到客户端。为了清晰起见,我们分开来看。

    (3) Certificate (客户端<–服务器)

    服务器向客户端发送证书清单。证书清单是一组 X.509v3 证书序列,首先发送的是服务器(发送方)的证书,然后会按顺序发送对服务器证书签名的认证机构的证书 。客户端会对服务器发送过来的证书进行验证 。

    在这里插入图片描述

    (4)ServerKeyExchange (客户端<–服务器)

    当 Certificate 消息不足以满足需求时,服务器会通过 ServerKeyExchange 消息向客户端发送一些必要信息 。

    具体所发送的信息内容会根据所使用的密码套件而有所不同 。

    当不需要这些信息时,将不会发送 ServerKeyExchange 消息 。

    在这里插入图片描述

    上图的Pubkey应该是ECDHE算法需要的两个随机数中的一个。使用rsa算法,对client hello 的随机值,server hello 的随机值,Pubkey值进行签名,表明服务端有对应证书的私钥。

    (5)CertificateRequest (客户端<–服务器)

    服务端要看客户端的证书。访问百度,不需要对客户端进行认证,所以没有该消息。

    (6)ServerHelloDone (客户端<–服务器)

    表示从 ServerHello 消息开始的一系列消息的结束 。

    在这里插入图片描述

    (7) Certificate (客户端–>服务器)

    服务器读取客应端的证书并进行验证。当服务器没有发送 CertificateRequest 消息时, 客户端不会发送 Certificate 消息 。所以,没有该消息。

    接下来的Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message在一个数据包中。为了清晰起见,我们分开来看。

    (8)ClientKeyExchange (客户端–>服务器)

    当密码套件中包含 RSA 时, 会随 ClientKeyExchange 消息一起发送经过加密的预备主密码 。
    当密 码 套 件中包含趴ffie-Hellman 密钥交换时, 会 随 ClientKeyExchange 消息 一 起发送 Diffie-Hellman 的公开值 。

    在这里插入图片描述

    (9) CertificateVerify (客户端–>服务器)

    客户端只有在服务器发送 CertificateRequest 消息时才会发送 CertificateVerify 消息 。 这个消息的目的是向服务器证明自己的确持有客户端证书的私钥 。所以,没有该消息。

    (10)ChangeCipherSpec (客户端–>服务器)

    实际上, ChangeCipherSpec 消息并不是握手协议的消息,而是密码规格变更协议的消息 。

    在 ChangeCipherSpec 消息之前,客户端和服务器之间已经交换了所有关于密码套件的信息,因此在收到这一消息时,客户端和服务器会同时切换密码 。

    在这一消息之后, TLS 记录协议就开始使用双方协商决定的密码通信方式了 。

    在这里插入图片描述

    (11)Encrypted Handshake Message (客户端–>服务器)

    参考: Encrypted Handshake MessageTLS/SSL 协议详解 (19) Encrypted handshake message

    The TLS handshake is concluded with the two parties sending a hash of the complete handshake exchange, in order to ensure that a middleman did not try to conduct a downgrade attack.

    1.这个报文的目的就是告诉对端自己在整个握手过程中收到了什么数据,发送了什么数据。来保证中间没人篡改报文。
    2.其次,这个报文作用就是确认秘钥的正确性。因为Encrypted handshake message是使用对称秘钥进行加密的第一个报文,如果这个报文加解密校验成功,那么就说明对称秘钥是正确的。(来自:https://blog.csdn.net/foshengtang/article/details/109066047)

    在这里插入图片描述

    接下来的New Session Ticket, Change Cipher Spec, Encrypted Handshake Message在一个数据包中。为了清晰起见,我们分开来看。

    (12)New Session Ticket (客户端<–服务器)

    参考:Session Ticket

    我们来看下它的流程,首先客户端在ClientHello的扩展中带上session_ticket扩展表示它想使用session_ticket功能,服务端如果同意则在ServerHello中回复session_ticket扩展项。服务端不用保存session,而是加密之后通过NewSessionTicket消息发送给客户端。这里session ticket key实际上是个对称密钥,它只有服务端自己知道。

    后续客户端想要重用该Session,在ClientHello扩展中把之前那个session_ticket塞进去,服务端成功解密且验证通过之后就进行会话重用,否则回退到完整的握手。然后还是同样地根据主密钥重新派生出会话密钥。

    这样服务端没有了保存session的负担,但是天下没有免费的午餐,session ticket对前向安全性会带来一定的损害。因为session ticket只是单纯使用session ticket key进行加密的,如果session ticket key泄漏了,那么之前基于会话重用的握手就都可以被破解了。

    所以在实际使用时,session ticket key应该经常更换,减小前向安全性方面的风险。

    在这里插入图片描述

    (13)ChangeCipherSpec (客户端<–服务器)

    这次轮到服务器发送 ChangeCipherSpec 消息了 。
    服务器:“好,现在我要切换密码了 。 ”

    在这里插入图片描述

    (14)Encrypted Handshake Message (客户端<–服务器)

    介绍同“(11)Encrypted Handshake Message (客户端–>服务器)”。

    在这里插入图片描述

    (15)到上面,握手结束,之后可以传送加密消息流(客户端<–>服务器)

    在此之后,客户端和服务器会使用应用数据协议和 TLS 记录协议进行密码通信 。

    在这里插入图片描述

    我们通过抓包的方式,一步步的看见了TLS的握手过程。接下来,我们验证下,我们是否真的搞明白了整个握手过程

    下面这张图来自catbro666-TLS ECDHE密钥交换时的认证

    这张图和上面整个过程有一个地方不同的是图中的server端生成了两个DH param,而上面显示的是server和client各生成一个DH param。

    在这里插入图片描述


    TLS安全连接的客户端程序 – 非完整代码

    参考代码:基于C++和OpenSSL实现的SSL网络通信SSL编程- 简单函数介绍

    中文的互联网还不够大,没有大到可以容易的找到参考示例代码。

    上面两个连接的示例也不大好:使用socket而非BIO_socket;没有考虑回调函数该如何实现;

    因为一些原因,下面非完整代码,但它能指导写出完整代码。


    客户端类 – 代码示例

    总体的逻辑思路如下图所示。(图片来自:SSL/TLS安全通信

    请添加图片描述

    代码如下所示。其中包含三个自定义的头文件。

    • exception.hpp,是异常头文件。根据自己需要自行实现,可参考《Boost程序完全开发指南》4.7 exception。
    • cb.hpp,是回调函数头文件。不会给出具体的代码,但会介绍如何去实现。
    • socket.hpp,套接字相关的头文件。会给出具体代码,见后文。
    #pragma once
    
    #include "exception.hpp"
    #include "cb.hpp"
    #include "socket.hpp"
    
    #include <openssl/ssl.h>
    #include <openssl/bio.h>
    #include <openssl/err.h>
    
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    #include <string>
    
    class TLSClient
    {
    private:
        int socket;
        SSL_CTX* ctx = nullptr;
        SSL* ssl = nullptr;
        char ERR[1024] = {0};
    public:
        TLSClient(std::string host, std::string port, 
                    std::string private_key_path, std::string cert_path,
                    std::string CAfile, std::string CApath);
        ~TLSClient();
    };
    
    
    TLSClient::TLSClient(std::string host, std::string port, 
                    std::string private_key_path, std::string cert_path,
                    std::string CAfile, std::string CApath)
    {
        // TLS_client_method():协商最高可用 SSL/TLS 版本
        // SSL_METHOD: Used to hold SSL/TLS functions
        // 这里可能没有做到强异常安全。openssl似乎没有提供单独释放SSL_METHOD空间的方法。可能是动态库的静态空间?
        const SSL_METHOD* meth = TLS_client_method(); 
        ctx = SSL_CTX_new(meth);
        if(ctx == nullptr) {
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
    
        // 设置msg_callback
        BIO* bio_c_out = BIO_new_fp(stdout,BIO_NOCLOSE);
        if(bio_c_out == nullptr) {
            SSL_CTX_free(ctx);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        SSL_CTX_set_msg_callback(ctx, msg_cb);
        SSL_CTX_set_msg_callback_arg(ctx, bio_c_out);
    
        // 客户端验证服务器证书设置
        mydata_t mydata;
        // mydata.verbose_mode = 1; // 打印证书信息
        // mydata.always_continue = 1; // 验证失败后,继续握手
        // mydata.verify_depth = 5; // ca最深验证五层
        mydata_index = SSL_get_ex_new_index(0, (void*)"mydata index", NULL, NULL, NULL);
    
        SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER, verify_cb);
        const char* CAfile_str = CAfile.empty() ? nullptr : CAfile.c_str();
        const char* CApath_str = CApath.empty() ? nullptr : CApath.c_str();
        if(!SSL_CTX_load_verify_locations(ctx, CAfile_str, CApath_str))
        {
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        // 为SSL会话加载用户证书
        if(!SSL_CTX_use_certificate_file(ctx, cert_path.c_str(), SSL_FILETYPE_PEM)) {
            SSL_CTX_free(ctx);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        // 为SSL会话加载用户私钥
        if(!SSL_CTX_use_PrivateKey_file(ctx, private_key_path.c_str(), SSL_FILETYPE_PEM)) {
            SSL_CTX_free(ctx);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
        
        // 验证私钥和证书是否相符
        if(!SSL_CTX_check_private_key(ctx)) {
            SSL_CTX_free(ctx);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
    
        // 三次握手
        if(!tcp_init(socket, host, port)) {
            BIO_closesocket(socket);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        ssl = SSL_new(ctx);
        if(ssl == nullptr) {
            SSL_CTX_free(ctx);
            BIO_closesocket(socket);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        if(!SSL_set_ex_data(ssl, mydata_index, &mydata)) {
            SSL_CTX_free(ctx);
            BIO_closesocket(socket);
            SSL_free(ssl);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        if(!SSL_set_fd(ssl,socket)) {
            SSL_CTX_free(ctx);
            BIO_closesocket(socket);
            SSL_free(ssl);
            int n = ERR_get_error();
            ERR_error_string(n, ERR);
            BOOST_THROW_EXCEPTION(tls_client_err()
                <<err_str(ERR));
        }
    
        if(SSL_connect(ssl) != 1) {
        	SSL_CTX_free(ctx);
            BIO_closesocket(socket);
            SSL_free(ssl);
            int err;
            SSL_get_error(ssl, err);
            BOOST_THROW_EXCEPTION(tls_client_err()
                 <<err_str("SSL_connect fail. The err code is ")
                 <<err_num(err));
        }
        
    }
    
    
    TLSClient::~TLSClient()
    {
        BIO_closesocket(socket);
        SSL_CTX_free(ctx);
        SSL_free(ssl);
    }
    
    
    

    客户端类 – 代码分解

    程序 == 数据结构 + 操作数据结构的算法

    类 == 成员变量 + 成员方法

    下面按照这个思路,拆解上面代码。


    SSL_CTX

    SSL_CTX :这是由服务器或客户端在每个程序生命周期中创建一次的全局上下文结构,它主要保存稍后为连接创建的SSL结构的默认值。

    使用SSL_CTX_new()创建SSL_CTX结构:将密码列表、会话缓存设置、回调、密钥和证书以及选项初始化为其默认值。创建新的 SSL_CTX 对象可能会失败。失败时,需要检查错误堆栈以找出原因。

    下面的代码中,仅仅设置“回调,密钥,证书”选项。

    SSL_CTX_set_msg_callback:安装回调以观察协议消息。关键是void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) 类型的回调函数该如何实现。我没有自己写,因为能力不够,所以我选择了移植openssl/apps/lib/s_cb.c-msg_cb。(很容易移植出来,比自己写的强很多)

    SSL_CTX_set_verify:设置证书验证的各种各种 SSL/TLS 参数。难点在于int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx)类型的回调函数该如何实现。非常棒的是,官方尽然在下方给出了示例,写的挺漂亮。

    SSL_CTX_use_PrivateKey_file、SSL_CTX_use_certificate:加载用户的密钥和证书;单向认证不需要,双向认证才需要的函数;将存储在文件中的第一个证书加载到ctx中;如果需要加载证书链,可以使用SSL_CTX_use_certificate_chain_file() ;如果内部需要存储多个私钥/证书对,可以使用SSL_CTX_set_cipher_list();如果在 TLS 协商过程中需要额外的证书来完成链,则在受信任的 CA 证书的位置额外查找 CA 证书,请参阅SSL_CTX_load_verify_locations(3);从文件加载的私钥可以加密。为了成功加载加密密钥,必须提供返回密码的函数,请参阅SSL_CTX_set_default_passwd_cb(3);使用回调函数SSL_CTX_set_client_cert_cb可以实现适当的选择例程或允许用户交互来选择要发送的证书。


    BIO_socket

    BIO是个好东西:BIO 是一种 I/O 抽象,它对应用程序隐藏了许多底层 I/O 细节。如果应用程序将 BIO 用于其 I/O,它可以透明地处理 SSL 连接、未加密的网络连接和文件 I/O。(这篇中文博客也很不错:OpenSSL中文手册之BIO库详解)

    所以相对于直接使用socket进行连接,比如chapter05_TCP客户_服务器示例,我更加倾向于于使用BIO_socket

    下面代码适用于tcp/ipv4连接。如果想写出通用的连接代码,可参考openssl/apps/lib/s_socket.c-init_client

    bool tcp_init(int& socket, const std::string& host, const std::string& port)
    {
        // https://www.openssl.org/docs/man1.1.1/man3/BIO_ADDR.html
        // https://www.openssl.org/docs/man1.1.1/man3/BIO_socket.html
        
        socket = BIO_socket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0);
    
        struct in_addr ip;
    
        int result = inet_pton(AF_INET,host.c_str(),&ip);
        if(result == 0) {
            printf("src does not contain a character string representing a valid network address \
                        in the specified address family.\n");
            return false;
        } else if(result == -1) {
            printf(" af does not contain a valid address family, \
                        and errno is set to EAFNOSUPPORT.\n");
            return false;
        }
    
        BIO_ADDR* serv_addr = BIO_ADDR_new();
        if(serv_addr == nullptr) {
            printf("BIO_ADDR_new fail\n");
            return false;
        }
    
        if(!BIO_ADDR_rawmake(serv_addr,AF_INET,&ip,sizeof(ip),htons(std::stoi(port)))) {
            printf("BIO_ADDR_rawmake fail\n");
            return false;
        }
    
        if(!BIO_connect(socket, serv_addr, 0)) {
            printf("BIO_connect fail\n");
            return false;
        }
    
        BIO_ADDR_free(serv_addr);
        return true;
    }
    

    SSL

    SSL (SSL Connection):这是主要的 SSL/TLS 结构,由服务器或客户端根据已建立的连接创建。这实际上是 SSL API 中的核心结构。在运行时,应用程序通常处理这个结构,它与大多数其他结构都有链接。(创建网络连接后,可以将其分配给SSL对象。使用SSL_new()创建SSL对象后,可以使用 SSL_set_fd()SSL_set_bio()将网络连接与对象相关联。)

    SSL_new():创建一个新的SSL结构,用于保存 TLS/SSL 连接的数据。新结构继承了底层上下文ctx的设置:连接方法、选项、验证设置、超时设置。(SSL结构是引用计数的。首次创建SSL结构会增加引用计数。释放它(使用 SSL_free)会减少它。当引用计数降至零时,分配给SSL结构的所有内存或资源都将被释放。??)

    SSL_set_fd() :将文件描述符fd设置为ssl的 TLS/SSL(加密)端的输入/输出工具。fd通常是网络连接的套接字文件描述符。执行操作时,会自动创建一个套接字 BIO来连接ssl和fd。BIO 和 SSL 引擎继承了fd的行为。如果fd是非阻塞的,则ssl也将具有非阻塞行为。

    SSL_connect():启动与 TLS/SSL 服务器的 TLS/SSL 握手。

    展开全文
  • SSL/TLS握手过程

    2022-05-19 15:39:27
    SSL/TLS握手过程可以根据秘钥生成的方式不同分为RSA握手过程和DH握手过程,分别使用RSA非对称加密方法和DH秘钥交换算法生成客户端和服务端共享的秘钥。 基础知识 RSA 非对称加密算法的原理 欧拉函数 欧拉函数用来...


    SSL/TLS握手过程可以根据秘钥生成的方式不同分为RSA握手过程和DH握手过程,分别使用RSA非对称加密方法和DH秘钥交换算法生成客户端和服务端共享的秘钥。

    基础知识

    RSA 非对称加密算法的原理

    欧拉函数

    欧拉函数用来计算对于给定的正整数 n n n,在小于等于 n n n的元素之中有多少个元素与其互质。其解析式如下:
    ϕ ( p k ) = p k − p k − 1 \phi(p^k) = p^k - p^{k - 1} ϕ(pk)=pkpk1
    如果 n n n为质数,则 ϕ ( n ) = n − 1 \phi(n) = n - 1 ϕ(n)=n1
    如果 n n n可以分解为两个互质的整数 p p p q q q之积,则 ϕ ( n ) = ϕ ( p ) ϕ ( q ) \phi(n) = \phi(p)\phi(q) ϕ(n)=ϕ(p)ϕ(q)

    欧拉定理

    如果两个正整数 a a a n n n互质,则 n n n的欧拉函数可以让如下等式成立:
    a ϕ ( n ) ≡ 1 ( m o d   n ) a^{\phi(n)} \equiv 1(mod\ n) aϕ(n)1(mod n)

    模反元素

    如果 a a a n n n互质,则一定存在元素 b b b,使得如下等式成立:
    a b ≡ 1 ( m o d   n ) ab \equiv 1(mod\ n) ab1(mod n)
    b b b a a a的模反元素。

    RSA密钥生成过程

    1. 选取两个不相等的质数 p p p q q q
    2. 计算 n = p q n = pq n=pq的欧拉函数 ϕ ( n ) = ϕ ( p q ) = ϕ ( p ) ϕ ( q ) = ( p − 1 ) ( q − 1 ) \phi(n) = \phi(pq)=\phi(p)\phi(q) = (p - 1)(q-1) ϕ(n)=ϕ(pq)=ϕ(p)ϕ(q)=(p1)(q1)
    3. 随机选择一个整数 e e e,并计算其对于 ϕ ( n ) \phi(n) ϕ(n)的模反元素 d d d,则 ( n , e ) (n,e) (n,e)作为公钥, ( n , d ) (n,d) (n,d)作为私钥,其他数字 p , q , n , ϕ ( n ) p,q,n,\phi(n) p,q,n,ϕ(n)不公开。
      如果一个攻击者在得知公钥的情况下获取私钥,需要根据 n , e n,e n,e计算出 d d d
      因为 d d d e e e关于 ϕ ( n ) \phi(n) ϕ(n)的模反元素,因而计算 d d d需要知道 ϕ ( n ) \phi(n) ϕ(n),而计算 ϕ ( n ) \phi(n) ϕ(n)则需要找到两个质数 p p p q q q,因为 ϕ ( n ) = ( p − 1 ) ( q − 1 ) \phi(n) = (p-1)(q-1) ϕ(n)=(p1)(q1)。而对于大整数的因数分解过程是非常耗时的,只有暴力一种解法。因而RSA算法被认为是安全的。

    DH密钥交换算法的原理

    DH秘钥交换算法涉及到离散对数的知识。选取两个大数 p p p g g g并公开,其中 p p p是一个质数, g g g p p p的模 p p p本原单位根,则DH密钥交换算法的流程为:

    1. Alice随机选择一个整数 a a a,计算 K a = a g   m o d   p Ka=a^g\ mod\ p Ka=ag mod p并将其发送给Bob;
    2. Bob随机算则一个证书 b b b,计算 K b = b g   m o d   p Kb=b^g\ mod\ p Kb=bg mod p并将其发送给Alice;
    3. Allice和Bob开始通过已知的信息计算密钥。Alice计算密钥 k e y = a × K b   m o d   p = a × b g   m o d p = ( a b ) g   m o d   p key=a\times Kb\ mod\ p=a\times b^g\ mod p = (ab)^g\ mod\ p key=a×Kb mod p=a×bg modp=(ab)g mod p,Bob计算密钥 k e y = b × K a   m o d   p = b × a g   m o d   p = ( b a ) g   m o d   p = ( a b ) g   m o d   p key=b\times Ka\ mod\ p= b\times a^g\ mod\ p = (ba) ^ g\ mod\ p = (ab) ^g\ mod\ p key=b×Ka mod p=b×ag mod p=(ba)g mod p=(ab)g mod p,所以Alice和Bob计算出的密钥相同。

    基于以下原因:

    已知 a a a,计算 b = a g   m o d   p b = a^g\ mod\ p b=ag mod p容易,但是在已知 b , g , p b,g,p b,g,p的情况下计算a很难(很难的意思是计算出结果需要很长很长时间)。函数 f ( x ) = x g   m o d   p f(x)=x^g\ mod\ p f(x)=xg mod p在密码学中被称为陷门函数,因为已知 x x x f ( x ) f(x) f(x)简单,但是已知 f ( x ) f(x) f(x) x x x很难。

    假设有一个中间人Eve通过窃听得到了 p , g , K a , K b p,g,Ka,Kb p,g,Ka,Kb,要想求得Alice和Bob协商得到的密钥 k e y key key,其必须求得 a a a b b b才能算出密钥,因而 k e y key key被认为是安全的,除了Alice和Bob外没人能知道。

    RSA握手过程

    客户端 服务端 client hello {支持的TLS版本、加密和压缩算法、随机数C} server hello {支持的TLS版本、选择的加密和压缩算法、随机数S} 服务端证书 其他 server hello done 验证证书 pre_master随机数,使用server的公钥加密 change Cipher spec:使用协商的加密算法和秘钥加密信息 握手结束通知,使用协商的密钥和加密算法发送之前发送所有信息的哈希值。 使用pre_master、C和S生成密钥,解密哈希值验证消息。 change cipher spec:使用协商的加密算法和秘钥加密信息。 握手结束通知,发送加密的所有之前发送信息的哈希值 客户端 服务端

    DH握手过程

    客户端 服务端 client hello {支持的TLS版本、加密和压缩算法、随机数C} 使用私钥加密DH参数、客户端和服务端生成的随机数生成数字签名 server hello {支持的TLS版本、选择的加密和压缩算法、随机数S、数字签名} 验证数字签名 确认数字签名 { 客户端DH参数 } 计算会话密钥 计算会话密钥 change Cipher spec:通知后续使用协商的加密算法和秘钥加密信息 握手结束通知,使用协商的密钥和加密算法发送之前发送所有信息的哈希值。 change cipher spec:通知后续使用协商的加密算法和秘钥加密信息。 握手结束通知,发送加密的所有之前发送信息的哈希值 客户端 服务端

    素性检验:如何生成一个大质数

    方法1: 筛法。判断整数 n n n是否为素数的方法是 n   m o d   i = 0 , i ∈ [ 2 , n ) n\ mod\ i = 0, i \in [2, \sqrt{n}) n mod i=0,i[2,n ),即从2开始遍历直到 n \sqrt{n} n ,如果没有整数能被 n n n整除则认为 n n n是素数。
    方法2: 利用费马小定理。费马小定理的内容为:

    假设 a a a是整数, n n n是一个质数,则有如下条件成立:
    a n − 1 ≡ 1 ( m o d   n ) a^{n-1} \equiv 1(mod\ n) an11(mod n)

    费马小定理是判断一个数是否为质数的充分条件,即存在合数满足费马小定理,这些合数被称为迈克尔数。最小的迈克尔数为561。
    利用费马小定理检验素数的方法被称为费马素性检验。费马素性检验是指通过多选择几个整数,如果满足费马小定理则 n n n是素数的可能性会很大。费马素性检验是概率性算法。
    米勒—拉宾算法和AKS算法利用费马小定理进行素性检验。其中米勒—拉宾算法是概率性算法,在实际生活中应用较多,而AKS算法是确定性算法。两者都是多项式时间复杂度。

    展开全文
  • 解码包含 TLS 握手的 pcap 文件 输入文件是使用以下方法创建的: tcpdump -nn -i any -w outfile.pcap 'tcp and port 443 and tcp[(((tcp[12:1] & 0xf0) >> 2)):1] = 0x16 and ((tcp[(((tcp[12:1] & 0xf0) >> 2)+...
  • TLS握手的过程

    2021-04-17 10:45:39
    翻译自 ...The TLS client sends a client hello message that lists cryptographic information such as the TLS version and, in the client’s order of preference, the CipherSuites supported .

    翻译自 https://www.ibm.com/docs/en/ibm-mq/9.0?topic=tls-overview-ssltls-handshake

    1. The TLS client sends a client hello message that lists cryptographic information such as the TLS version and, in the client’s order of preference, the CipherSuites supported by the client. The message also contains a random byte string that is used in subsequent computations. The protocol allows for the client hello to include the data compression methods supported by the client.

    TLS客户端发送client hello,里面包含了加密的信息,如TLS version, client支持的加密方式,客户端随机字符串,如下图所示

    client hello

    1. The TLS server responds with a server hello message that contains the CipherSuite chosen by the server from the list provided by the client, the session ID, and another random byte string. The server also sends its digital certificate. If the server requires a digital certificate for client authentication, the server sends a client certificate request that includes a list of the types of certificates supported and the Distinguished Names of acceptable Certification Authorities (CAs).

    TLS服务端响应server hello消息,包含了服务端选择的加密方式, session ID, 以及服务器端随机字符串。 服务器同时发送certificate给Client。 如果服务端要求客户端做证书验证,服务端会发起一个client certificate request(客户端证书验证请求),包含支持的加密方式和可接收的CA。
    客户端验证不是必须的,它从另一层保证了client的真实有效性,避免了一些非法用户的攻击行为,但是同时也增加了服务器的资源开销。

    server hello

    certificate消息和Server Hello Done消息

    1. The TLS client verifies the server’s digital certificate. For more information, see How TLS provides identification, authentication, confidentiality, and integrity.

    client验证server的certificate

    1. The TLS client sends the random byte string that enables both the client and the server to compute the secret key to be used for encrypting subsequent message data. The random byte string itself is encrypted with the server’s public key.

    TLS client根据客户端和服务端的信息生成secret key,使用服务器证书的public key加密,然后发送给Server。后续的通信将采用该secret key做对称加密。

    Client Key Exchange

    1. If the TLS server sent a client certificate request, the client sends a random byte string encrypted with the client’s private key, together with the client’s digital certificate, or a no digital certificate alert. This alert is only a warning, but with some implementations the handshake fails if client authentication is mandatory.

    如果Serve要求client certificate request,那么client会发送client的certificate,同时使用client的certifcate私钥机密的随机字符串;如果客户端没有certificate,那么会给一个无证书的通告。这个通告仅仅是个告警,但是有些强制要求client验证的实现会导致tls握手失败。

    1. The TLS server verifies the client’s certificate. For more information, see How TLS provides identification, authentication, confidentiality, and integrity.

    如果收到client certificate,Server会验证client‘s certificate

    1. The TLS client sends the server a finished message, which is encrypted with the secret key, indicating that the client part of the handshake is complete.

    TLS client发送包含secret key的finished消息,表示client端TLS握手完成

    1. The TLS server sends the client a finished message, which is encrypted with the secret key, indicating that the server part of the handshake is complete.

    TLS server发送finished消息,表示server端TLS握手完成

    1. For the duration of the TLS session, the server and client can now exchange messages that are symmetrically encrypted with the shared secret key.

    握手完成后,整个session对话过程Server和Client可以使用协商好的secret key用对称加密方式通信了。

    TLS handshake

    展开全文
  • SSL/TLS握手协议概述

    2021-09-16 21:52:57
    TLS协议中存在连接和会话的概念,会话上的加密信息是通过TLS握手协议进行协商的。 连接代表一种特定的通信通道(通常映射为TCP 连接),以及密钥、加密选择和序号状态等内容。 会话则是一种虚拟的结构,它代表...
  • 基于RSA的TLS握手流程

    2021-09-16 22:30:41
    文章目录3.2 基于RSA的TLS握手流程3.2.1 TLS第一次握手3.2.2 TLS第二次握手3.2.3 TLS第三次握手3.2.4 TLS第四次握手 3.2 基于RSA的TLS握手流程 先看看基于RSA进行密钥配送的TLS握手报文如下: TLS四次握手的报文...
  • TLS 协议是由TLS 记录协议和TLS 握手协议这两层协议叠加而成的,位于底层的TLS 记录协议负责进行信息传输和认证加密,位于上层的TLS 握手协议则负责除加密以外的其它各种操作,比如密钥协商交换、身份认证等。...
  • 本文想写介绍传输层安全协议TLS握手过程
  • SSL/TLS专栏说明 本文的初衷是:随着数字信息时代的到来(DT), 生活中的方方面面几乎可以完全数字信息化,例如个人性别、地址、联系方式、财产、生活习惯、饮食习惯、工作情况、学历信息、健康状况、兴趣爱好等等...
  • TLS握手过程及wireshark抓包分析

    千次阅读 2021-08-05 19:08:17
    TLS握手过程及wireshark抓包分析 1.TLS的发展 1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。 1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。 1996年,SSL 3.0版问世...
  • 本文的初衷是:**深入学习SSL/TLS协议**。 在工作过程中做了2年的IPSecVPN, 在此过程中经常遇到将IPSe与SSL对比的情景:包括各自的协议异同、应用场景、协议本身复程度以及用户易用性等各个方面。在做IPSec的这段...
  • TLS握手协议详解

    千次阅读 2018-10-17 18:52:55
    握手协议是TLS握手协议的一部分,负载生成共享密钥以及交换证书。其中,生成共享密钥是为了进行密码通信,交换证书是为了通信双方相互进行认证。 握手协议这一名称中的“握手”,是服务器和客户端在密码通信之间...
  • TLS 握手共分四个阶段,为了便于理解,我用wireshark抓了包来分析每一个阶段: Client Hello(第一次握手): 客户端首先会发一个「Client Hello」消息,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,...
  • HTTPS中的TLS握手

    2020-06-07 12:05:10
    TLS握手 握手目的:为对称加密安全交换秘钥 RSA经典握手 ECHDE握手:ECHDE算法参数交换,抢跑 TLS1.3握手:必须采用ECHDE算法,压缩为1RTT 1.握手目的 为了实现HTTPS通信的机密性,在通信刚开始的时候使用非对称...
  • Https工作原理&TLS握手机制

    千次阅读 2020-12-10 00:44:34
    Https工作原理&TLS握手机制 @Kyunban Wong HTTPS是在HTTP的基础上提供了数据加密的支持,保存了数据的私密性、完整性,并且可以用来认证客户端和服务端的身份。 在普通的HTTP中,数据是明文传输的,很容易出现中间...
  • 本文将探索整个SSL/TLS握手过程。 在此之前,先简述下最后这块内容的关键要点: TLS适用于对称密钥 对称密钥可以通过安全密钥交换算法共享 如果请求被截获,密钥交换可能会被欺骗 使用数字签名进行身份验证 ...
  • server_hello: 1.选择的协议版本号 2.选择的加密套件cipher suites 3.选择的加密算法 4.随机数random_S 5.证书链server_certificates 6.server_hello_done cipher suites: ...握手过程: 1.客户端对...
  • 快速了解TLS协议,并深入学习协议原理
  • TLS 握手优化详解

    2019-03-29 23:25:43
    HTTPS 在 TCP 和 HTTP 之间增加了 TLS(Transport Layer Security,传输层安全),提供了内容加密、身份认证和数据完整性三大功能,同时也给 Web 性能优化...TLS 的前身是 SSL(Secure Sockets Layer,安全套接字...
  • 上篇内容我们首先介绍什么是SSL / TLS握手的概念和简单的流程概述,为的就是让有的童鞋们能够更好地理解。那么接下来呢我们将介绍SSL/ TLS握手失败和错误(SSL握手错误)的所有可能原因以及谁可以修复它们。之后,...
  • mbedTLS握手过程log

    千次阅读 2019-11-07 17:34:48
    mbedtls: ssl_tls.c:6674 => handshake mbedtls: ssl_cli.c:3336 client state: 0 mbedtls: ssl_tls.c:2464 => flush output mbedtls: ssl_tls.c:2476 <= flush output mbedtls: ssl_cli.c:3336 client sta...
  • 本文的初衷是:**深入学习SSL/TLS协议**。在工作过程中做了2年的IPSecVPN, 在此过程中经常遇到将IPSe与SSL对比的情景:包括各自的协议异同、应用场景、协议本身复程度以及用户易用性等各个方面。在做IPSec的这段时间...
  • 发送消息处理clientHelloMsg选择合适的证书以及签名算法计算握手阶段的密钥以及发送Server的参数发送Server证书以及签名发送finishedMsg并再次计算密钥Client读消息&发送消息读取serverHelloMsg并计算密钥处理...
  • SSL/TLS握手失败如何修复?

    千次阅读 2020-09-08 09:21:17
    一、什么是SSL/TLS握手? 在每个HTTPS连接开始时,客户端(互联网用户的Web浏览器)和服务器(托管网站)都必须进行一系列检查-缺乏更好的期限-以便彼此进行身份验证并确定参数。加密的连接。这被称为TLS握手,业内...
  • 抓包分析SSL/TLS 握手过程详解

    千次阅读 2020-05-30 17:45:26
    如上图所示,在 HTTPS 加密中真正起作用的其实是 SSL/TLS 协议。SSL/TLS 协议作用在 HTTP 协议之下,对于上层应用...SSL/TLS 握手是为了安全地协商出一份对称加密的秘钥,这个过程很有意思,下面我们一起来了解一下。..
  • 深入学习Go源码中Server端TLS握手流程
  • TLS握手和算法

    千次阅读 2018-08-13 09:07:27
    这是一篇我写在“我就是程序员”的微信订阅号的里文章,原文的地址是:https://mp.weixin.qq.com/s/qgeFgO83uGoeuo__vkef9w &amp;nbsp;...HTTPS在HTTP通信建立连接的握手...图解TLS握手过程图中的女士Alise作为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,558
精华内容 11,423
关键字:

tls 握手