你可以带着以下目的进行学习:
SSL:安全套接字层(Secure Socket Layer),是TLS的前身。
TLS:安全传输层协议的简称(Transport Layer Security)。
历史发展时间线如上图所示。
1995年由Netscape发布 SSL 2.0
1996年由Netscape发布 SSL 3.0
1999年由IETF在RFC 2246中首次定义 TLS 1.0,作为SSL 3.0的升级
2006年由IETF在RFC 4346发布 TLS 1.1
2008年由IETF在RFC 5246发布 TLS 1.2
2018年由IETF在RFC 8446发布 TLS 1.3
2011年弃用 SSL 2.0
2015年弃用 SSL 3.0
2020年弃用 TLS 1.0 与 TLS 1.1
截至2020年,只有TLS 1.2和TLS 1.3仍然有效。
举三个生活中常用的示例:
TLS 为我们解决了 3 件事:
如上图所示,TLS工作流程由2个阶段(或2个协议)组成:
1、握手协议(Handshake protocol),其主要目的是进行身份验证和密钥交换,该阶段主要涉及以下步骤:
- 协商 TLS 协议版本。
- 选择密码算法或密码套件。
- 通过非对称密钥相互认证。
- 建立一个将用于下一阶段的共享密钥(对称加密密钥)。
2、记录协议(Record protocol),其主要目的是确保消息传输的机密性和完整性,该阶段主要涉及以下步骤:
- 使用握手中建立的共享密钥对发出的消息进行加密。
- 将加密后的消息传输到另一侧。
- 验证消息是否在传输过程中进行了修改。
- 使用握手中建立的共享密钥对接收的消息进行解密。
由于客户端与服务器大量的数据加解密交换发生在记录协议阶段,故又因该阶段解密数据量很大,又称该阶段为批量加密。
可以看出,TLS在整个流程中同时使用了对称和非对称加密两种方式,那为什么不只使用一个?
在介绍SSL/TLS的完整握手流程之前,我们先了解下对称加密与非对称加密的相关内容,关于SSL/TLS的完整握手流程将在第四个大标题中讲解。
(如上图所示)首先,Alice有一条纯文本消息,她想发送给Bob,但不希望互联网中的任何人都可以阅读。因此她使用他们之前彼此共享过的共享密钥(Shared secret key)对消息进行加密,然后通过互联网将加密的消息发送给Bob,Bob收到加密的消息后,他可以轻松的使用相同的密钥对其进行解密。由于该密钥用于加密和解密,且加密和解密的过程是对称的,故称该过程为对称加密过程。
似乎加密的数据就很安全?黑客仍然可以采用翻转攻击的方式破坏加密后的数据。
(如上图所示)现在,有一个可以在互联网上捕获他们交流信息的黑客Harry。但是,该消息已被加密,而Harry没有密钥,因此他将无法对其解密。但是他仍然可以改变消息,通过一种称为翻转攻击的技术。假设这一次,Alice不是在跟Bob通信,而是在和她的网上银行通信,此时Alice想转账$100给某人,该消息通过密钥进行加密后通过互联网发送给银行。此时,Harry捕获到了加密的消息,虽然他无法解密,但是他可以将某些位从1翻转为0,从0翻转为1,然后将修改后的消息转发到银行,当银行解密后将获得不同的消息内容,在这种情况下,转账金额变成了$900而不是$100,因此非常危险。
那么,这就是需要我们在收到加密的数据后,有方法确保加密的消息在传输过程中未被更改。该如何确保呢?使用认证加密。
认证加密包括对消息的加密和验证过程。
(如上图所示)该指示的是加密的过程,该过程可分为两个步骤,其一是对消息的加密,其二是为加密信息生成消息认证码。
(如上图所示)在TLS 1.3中,除了加密的消息外,我们还想验证一些关联数据(Associated Data),例如地址(addresses)、端口(ports)、协议版本(protocol version)或序列号(sequence number),这些信息是未加密,且通信双方均知晓的 。在TLS 1.3中,将这些关联数据也作为MAC算法的输入,因此,整个过程又称为带有关联数据的认证加密(Authenticated Encryption with Associated Data,简称AEAD)
接下来我们将看到Bob如何验证加密的消息在传输过程中是否被更改。
(如上图所示)这是一个加密的反向过程。
从带有MAC的加密消息开始,我们将从加密的消息中经过提取(Untag)过程,获的MAC(ae6f21b)和不带有MAC的加密消息。然后,加密的消息、共享密钥、随机数(注意该随机数和加密过程中的随机数相同,在将消息发送给对方时,会将随机数填充到加密的消息中)以及关联数据作为MAC算法的输入,然后输出一个新的MAC值。现在,Bob可以简单地比较两个MAC值,如果它们不同,则表示加密的消息已被更改,否则,他可以安全地解密内容,并充分相信这与Alice发送的消息相同。
但是,Bob和Alice如何在不泄露给公众的情况下实现共享密钥的交换?
(如上图所示)为此,他们需要使用一种能够生成共享密钥的密钥建立协议,例如Diffie-Hellman Ephemeral(DHE)或Elliptic Curve Diffie-Hellman Ephemeral(ECDHE)。
接下来我们了解下Diffie-Hellman在密钥交换中的工作原理。
(如上图所示)首先基数 g 和模数 p,这两个数字是众所周知的,且Bob和Alice都知晓这两个数字。其次Bob和Alice都拥有一个私钥,Alice的私钥是 a,Bob的私钥是 b。准备就绪后,现在开始进行密钥交换:
因此,Alice和Bob具有了相同的密钥S,而没有将其泄露给公众。
但是请记住,不同加密算法输出的密钥长度是不相同的。因此,Alice和Bob必须使用相同的密钥派生函数制作密钥,输出相同长度的密钥S。在TLS 1.3中,使用的密钥派生函数是HMAC-based key derivation function,所以这是为什么命名HKDF的原因。
让接下来我们将进一步了解密钥派生函数工作原理。
密钥派生函数(Key Derivation Function),简称KDF。
(如上图所示)通常,KDF需要五个输入参数:
通过这些输入参数,KDF将输出指定长度的密钥(Key of required length)。
陷门函数(Trapdoor function),是一种进行正向计算很容易,反向计算极其困难的函数。
(如上图所示)现在,我们继续讨论Diffie-Hellman密钥交换问题。在Diffie-Hellman示例中,由于p、g、A、B都是众所周知的,这意味着黑客Harry也可以访问这些数字。我们可能会产生疑问:根据p、g、A、B和给定函数能否计算出a、b和S?这种密钥交换机制安全吗?
答案是安全的,因为这些用于计算的函数均是陷门函数。例如,如果我们为p、g、a、b选择好一个值,例如选择p作为2048位素数,选择g作为p的模,并选择a、b为256位随机整数,在这种情况下,给定p、g和a很容易计算出A,但是给定p、g和A,要计算出a很难。很容易看书,A可以用O(log(a)) 时间复杂度快速计算,这是一个模块化求幂问题。另一方面,计算a是一个离散对数问题,计算起来要困难得多,这需要我们当前的计算机花费很长的时间解决。所以我们目前的使用Diffie-Hellman至少是安全的,或者直到下一代强大的量子计算机出现后才会受到影响。
虽然Diffie-Hellman是一个需要很长时间解决的问题,但是并不意味着无法解决,是吗?
如果我们在会话过程中使用的都是固定的密钥S,又名静态密钥(Static Key),将会产生潜在的危险,具体分析如下。
(如上图所示)如果Alice和Bob在他们交流的每个环节中,都使用固定的私钥a和b,然后发生的是,Harry可以记录所有这些会话,然后从Session1开始解决a问题,尽管他要花很长时间才能解决,假设在SessionN之后,他得到了正确的a,然后他可以用a来计算出密钥S,从而他将能解密出所有记录的会话内容。
以上情况看起来很吓人!我们要如何预防呢?
答案是使用临时密钥(Ephemeral Key)。
(如上图所示)顾名思义,我们在每个会话中使用不同的密钥(S1、S2…),即使Harry可以解决一次会话的密钥,他也不能将该密钥用于其他会话。这在TLS中称为完全前向保密(Perfect Froward Secrecy)。
目前为止,我相信你已经完全了解了Deffie-Hellman Ephemeral DHE的含义,即使用临时密钥的Deffie-Hellman密钥建立协议。
非对称加密可用于以下三个方面:
在学习数字签名算法之前,先来学习下非对称加密系统是如何工作的?
在非对称加密体系中:公钥和私钥是成对出现的,若是公钥加密,则私钥解密,若是私钥加密,则公钥解密,即互相解密,在私钥加密的情形中,又常称为私钥签名,公钥验证。即使用场景为:
(如上图所示)同对称加密一样,Alice想发送一条消息给Bob,但是这一次,没有共享密钥,而是使用非对称加密的公私钥,Alice使用Bob的公钥(Bob’s public key)对消息加密,并将加密的消息发送给Bob,当Bob收到消息时,它使用自己的私钥(Bob’s private key)对其进行解密,尽管公钥和私钥不同,但是它们仍然可以通过一些陷门函数关联在一起,就像我们在Diffie-Hellman算法中看到的一样。
在非对称加密的情况下,即使黑客Harry可以访问Alice的加密消息和Bob的公钥,他也不能使用Bob的公钥来解密消息。
由非对称加密原理可知,分享公钥变得极其简单,Bob可以直接通过互联网将密钥发送给Alice,无用担心公钥可用于解密任何消息。公钥分享的关键是完全公开的,因此,任何人都可以使用它来加密只有Bob可以阅读的消息,其分享流程如下图所示。
你认为这个公钥分享方案真的安全吗?
若直接使用以上公钥分享方案,其现实情况并不那么简单。
(如上图所示)尽管我们知道Harry不能使用Bob的公钥解密邮件,但他仍然可以干扰公钥的分享,并用他自己的公钥替换Bob的公钥。现在,当Alice收到公钥时,她仍然认为这是Bob的公钥,但实际上是Harry的公钥。因此,如果Alice使用此公钥加密她的消息,Harry可以用他的私钥解密消息,然后再用Bob的公钥对解密后的消息加密,再发送给Bob,如此一来,Bob和Alice在通信过程中对Harry无感知。发生这种情况的原因是,因为公钥只是一串数字,而没有身份信息可以告诉我们其所有者是谁。
那么我们应该如何解决没有身份信息的问题呢?
显然,我们应该将密钥与一些身份消息放在一起,然后再共享出去,即所谓的数字证书。于是,Bob把他的公钥放在证书里,证书上有他的姓名和其他身份信息,该证书就像现实世界中的护照一样。
但是我们如何知道真正拥有证书的是Bob?是如何阻止了Harry用Bob的名字,但用Harry的公钥制作假证书?
(如上图所示)就像现实世界中一样,护照必须由护照颁发机构经过身份验证的过程后签发。在数字世界中,证书必须由证书颁发机构验证并签名,该证书颁发机构和护照颁发机构均是受信任的第三方。
获取数字证书,即证书颁发机构对数字证书的颁发过程。
(如上图所示)Bob已有一对公钥和私钥,现在他准备开始申请证书颁发机构对数字证书的签名:
现在,Bob与Alice可以共享此证书,证书中包含Bob的公钥和一些身份信息,而不是像以前那样仅发送公钥,Alice收到证书后,Alice可以使用证书颁发机构的公钥轻松验证证书的真实性。因此,Harry无法再用他的公钥替换Bob的公钥,因为他没有CA的私钥来签名假证书。数字证书的共享流程如下图所示:
请注意,以上的安全的前提是我们都信任CA。如果以某种方式CA不可信,例如,如果CA给Harry他们的私钥,那么我们将面临严重的危险!解决CA可信问题的方法是,使用CA链。
CA链是为了解决CA的可信任问题。
(如上图所示)CA链的顶层是根证书颁发机构(Root Certificate Authority),它可以签署自身证书与签署中间CA(Intermediate Certificate Authority)证书。而该中间CA又可以签署其子节点CA证书,或者他们可以直接签署最终实体证书(即叶子证书)。如此,确保每个证书都引用了其上一节点的证书,可以追溯到根节点的证书,例如我们使用叶子节点的公钥解密(验证)叶子节点证书签名后,可以获得上一节点的签名,直至根节点。
在我们使用的操作系统和浏览器中存储了受信任的根证书颁发机构的证书列表,这样,操作系统和浏览器就可以轻松地验证所有证书的真实性。
(如上图所示)数字证书的签名与验证流程:
CA对证书的签名:
用户验证证书:
至此,我们已经了解了对称加密与非对称加密,下面将探索如何在TLS 的握手协议中使用这两种加密方式。
TLS 1.3 完整的握手流程主要包括以下三个步骤。
1、首先是客户端到服务器的Client Hello,消息内容包括:
- 支持的协议版本:TLS 1.3 或 TLS 1.2。
- 支持的对称密钥套件:TLS_AES_256_GCM_SHA384 或 TLS_CHACHA20_POLY1305_SHA256。
- 支持的密钥协定(交换)算法:DHE(Diffie-Hellman Ephemeral) 或 ECDHE(Elliptic-Curve Diffie-Hellman Ephemeral)。
- 分享的密钥:客户端的DHE公钥,客户端的ECDHE公钥,用于计算临时的共享密钥,即前文示例中的S。
- 支持的签名算法:RSA-PSS 或 ECDSA,由服务器选择使用哪种算法对整个握手进行签名。
2、 收到客户端的Client Hello后,服务器将回复一个Server Hello,消息内容包括:
- 选择的协议版本:TLS 1.3.
- 选择的对称密钥套件:TLS_AES_256_GCM_SHA384。
- 选择的密钥协定算法:DHE。
- 分享的密钥:服务器的DHE公钥。
- 证书请求:对客户端证书的请求,可选值,通常在HTTPS中,只需要服务器将其证书发送给客户端即可。。
- 服务器证书:服务器的证书。
- 证书验证:对整个握手消息的签名。生成方式:从客户端的握手开始,直到证书请求为止,都称为握手上下文(Handshake context),然后将握手的上下文以及服务器的证书经过Hash运算,得到一个hash值,例如4ab31d2,然后使用服务器的私钥对hash值进行签名,使用的签名算法为客户端支持的算法之一,最后获得填写的签名值。
- 服务完成:为一个MAC值(消息认证码)。生成方式:对握手上上下文+服务器证书+证书验证进行Hash运算,再将hash值通过所选的密码套件计算出MAC值。
3、客户端收到Server Hello后,将通过根CA验证服务器证书,然后检查签名和MAC值,确保消息没有被篡改。若一切顺利,则客户端将发送一个握手结束消息,结束消息中包括:
- 由握手上下文计算的MAC值、以及可选的客户端证书和证书验证。
以上便是TLS 1.3中的完整握手流程。
预共享密钥(Pre-Shared Key),简称PSK。
(如上图所示)为了提高效率,客户端与服务器并不会每次都经过完整的握手流程,有时他们仅执行简短的握手流程,实现方法是通过预共享密钥恢复状态:经过前一次握手,客户端与服务器已经相互了解,因此他们不需要再次进行身份验证,因此,服务器可以向客户端发送一个或多个会话凭证(session ticket),可以在下一次握手中用预共享密钥(PSK)、凭证过期时间以及其他一些信息用作身份验证。
在使用PSK的简短握手流程中,客户端将发送一条简单的问候消息,其中包括上一次握手获得的PSK身份标识(凭证)和PSK密钥交换模式,如果使用具有Diffie-Hellman模式的PSK,客户端还需要共享其Diffie-Hellman公钥。如有需要,允许服务器回退到完整的握手流程。服务器收到此客户端的问候消息时,它将返回带有选定的预共享密钥标识消息,服务器可在返回消息中带有可选的Diffie-Hellman公钥。最后,客户端发送给服务器一个完成消息。
可以看出,在该简短的握手流程中,客户端与服务器之间没有证书身份验证。这为零个往返时间(0-RTT)提供了机会。
0-RTT(Zero Round-Trip Time)意味着,客户端无需等待握手完成,就可将第一个应用请求数据发送给服务器。
(如上图所示)在0-RTT中,客户端将应用程序数据(Application data)和客户端Client Hello消息一起发送,客户端使用Pre-shared key字段中的第一个PSK派生的密钥对数据进行加密,同时,该Client Hello增加了早期数据指示(Early data indication)字段,告诉服务器有早期的应用数据正在发送。如果服务器接收此0-RTT请求,它会像正常的PSK恢复一样发送一个回复消息,可能回复消息中带有一些可选的应用程序数据。最后,客户端发送一个带有早期数据的结束与MAC值得结束消息。
以上就是TLS 1.3中0-RTT的工作方式。它的优点时将延迟减少了 1 个往返时间,但是,其缺点是将会收到重放攻击的潜在威胁,意思是,黑客可以复制并发送相同加密的0-RTT请求多次访问服务器,为了避免这种情况,必须实现服务器应用程序对重复请求的方式限制,例如1s之内只能访问5次。
整理文件的过程中,找到了早先实现的代码,逻辑与上图所示一致,实现语言为Go,可前往资源中心下载。
希望你也有所收获!
参考文献:A complete overview of SSL/TLS and its cryptographic system
文章浏览阅读2.1k次。手机邮箱注册技术分析及运用-如何用邮箱注册账号,请参考以下文章: https://blog.csdn.net/weixin_42828741/article/details/82625077本文主要讲述如何使用手机注册账号~目前了解到的服务商有以下几种: 阿里云短信 -腾讯云短信 -百度云SMS -容联云通讯(本文介绍的是这种)接入步骤(以容联云通讯为例测试) 1.注册开发..._手机号登录邮箱咋发验证码
文章浏览阅读1.1k次。1、登录企业微信管理后台 -- 创建企业内部应用 -- 填写logo和应用名称--配置域名 (与钉钉类似)这样ios在点击输入框的时候就不会出现页面被顶起来导致页面变形的问题了。3、配置首页可访问地址:打包到线上的路径(注意配置正式环境和本地环境)2、安装对应的插件和依赖。axios、router、scss等。2、上传内部应用logo和名字。注意需要添加可访问域名的配置。开发上线后会遇到很多有关安卓和ios的兼容性问题。4、在所在公司的工作台搜索应用名称即可。如果不添加配置会自动跳转到线上的地址。_做个app用于钉钉和企业微信用什么编程软件
文章浏览阅读255次。https://github.com/easy-mock/easy-mock常用linux命令查看端口占用情况netstat -lnpt |grep 80netstat -an|grep 7301系统管理角色,里面切换rootsudo su -查找一个叫 app 的进程ps -ef|grep app杀掉进程kill -9 pid1、安装nodejs 一定要安装8..._easymock部署在centos7中 不能访问
文章浏览阅读734次。二、EventLoop机制LibRIL负责接收来自RILJ的数据,并传递给ReferenceRIL。实现这一功能的主要机制就是EventLoop机制。 分析LibRIL主要就是分析EventLoop。2.1 EventLoop相关预备知识2.1.1 EventLoop中的Event在ril_event.h头文件中可以看到ril_event的结构体定义//定义Event回调函数指针typedef_rild_event
文章浏览阅读122次。公司使用 mailman 来显示 patch,mailman 显示的改动只有一堆黑白文字,难以辨认。有时候还把 patch 当成文件再 git add 一遍后再生成一个新的 patch,这时候对于原来 patch 的代码改动来说,整个 patch 都是新增代码,就更加难以看出改动在哪,给 review patch 带来不必要的不便。有天我想可不可以做成跟 github 一样,至少增删有不..._diff2htmlui
文章浏览阅读3k次,点赞2次,收藏15次。文章目录智能指针作为信号参数QSharedPointer智能指针作为信号参数/*! connect a module to the event bus*/Q_DECLARE_METATYPE( QSharedPointer<GitlEvent> )bool GitlEventBus::registerModule(GitlModuleDelegate* pcModule){ qRegisterMetaType< QSharedPointer<GitlEve_qsharedpointer 引用自定义类型
文章浏览阅读891次。[lingyun@localhost chdir]$ lschdir.c[lingyun@localhost chdir]$ cat chdir.c/********************************************************************************** Copyright: (C) 2013 fulinux* ..._linux chdir 函数
文章浏览阅读1.5k次。开发环境要求本系统的软件开发及运行环境具体如下。操作系统:Windows 7、Windows 10。Python版本:Python 3.7.0。开发工具:Python IDLE。运行方法在项目文件studentsystem.py上单击鼠标右键,在弹出快捷菜单中选择“Edit with IDLE\Edit with IDLE 3.7(64-bit)”菜单项,如图1所示。在打开的Python Shel..._python从键盘输入 n 个学生信息,包括学号、姓名、成绩。保存到 e:\students.txt
文章浏览阅读826次,点赞12次,收藏22次。随着社会的发展,系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但各种信息鱼龙混杂,信息真假难以辨别。为了方便用户更好的获得工厂生产设备维护信息,因此,设计一种安全高效的工厂生产设备维护管理系统极为重要。为设计一个安全便捷,并且使用户更好获取工厂生产设备维护信息,本文主要有安全、简洁为理念,实现用户快捷寻找工厂生产设备维护信息,从而解决工厂生产设备维护信息复杂难辨的问题。该系统采用java语言、Spring Boot框架和mysql数据库进行开发设计,通过对。
文章浏览阅读708次。mysql 基准测试_mysql基准测试
文章浏览阅读1.4k次。展开全部1、八进制化为32313133353236313431303231363533e78988e69d8331333366306436十进制:例:将八进制数12转换成十进制数 2、八进制化为二进制:规则:按照顺序,每1位八进制数改写成等值的3位二进制数,次序不变。例: (17.36)8 = (001 111 .011 110)2 = (1111.01111)23、八进制化为十六进制先..._两个八进制相加
文章浏览阅读1k次,点赞30次,收藏15次。例程涵盖:STM32各类功能配置,外围传感器初始化,模块初始化,物联网协议,操作系统移植,功能开发,产品案例等等,十分具有参考价值。_基于stm32f103单片机的经典应用实例源码合集(76例)