1990年互联网诞生时,超文本传输协议HTTP已经被用来传输数据,所以现在所有的网址都以http开头。然而,HTTP 协议以明文形式发送数据。任何捕获数据包的人都可以看到正在发送的数据,这显然不安全。 1994年,Netscape在HTTP中添加了加密协议,并开始在HTTP中添加SSL(安全套接字层)。以前称为“HTTP over SSL”或“HTTP Secure”,现在称为HTTPS。
HTTPS 实际上是一个“非常简单”的协议,只有7 页的RFC 文档指定了新的协议名称“https”和默认端口号443。另一种请求/响应模式和消息结构是请求。方法、URI、标头字段、连接管理等都与HTTP 完全相同,没有什么新意。
换句话说,除了协议名称“http”和端口号80 两点不同外,HTTPS 协议与HTTP 的语法和含义完全相同,而且其优缺点都是“可以接受的”(当然也有例外) 。 “安全”)用于“纯文本”和“明显文本”)。
SSL/TLS
SSL/TLS 是TCP/IP 七层协议中的会话层,用于验证用户和服务器、加密和解密数据,并保持数据完整性,使其在传输过程中不被修改。
SSL 有两个版本:v2 和v3,其中v1 由于严重缺陷而未公开可用。当SSL 发展到v3 时,它证明了自己是一种如此安全的通信协议,以至于互联网工程组IETF 在1999 年将其更名为TLS(传输层安全),并正式对其进行了标准化,版本号也从1.0 开始更改。所以TLS1.0实际上是SSLv3.1。
迄今为止,TLS已经开发了三个版本:2006年的1.1、2008年的1.2和去年(2018年)的1.3。每个新版本都密切跟踪加密技术的发展和互联网的当前状态,并不断增强安全性和性能。它已成为信息安全领域的权威标准。
TLS 1.2 是目前使用最广泛的协议,较旧的协议(TLS1.1/1.0、SSLv3/v2)被认为不安全,将在2020 年左右不受主流浏览器的支持,以下所有说明均针对TLS1。 2.
TLS由记录协议、握手协议、警报协议、密码更改规范协议、扩展协议等多个子协议组成,支持对称加密、非对称加密、身份认证等多种前沿密码技术,综合利用技术。当浏览器和服务器使用TLS 建立连接时,它们必须选择一组合适的加密算法来确保安全通信。这些算法的组合称为“密码套件”(也称为密码套件、密码套件)。
SSL/TLS分为对称加密和非对称加密两种方式。
对称加密
对称加密是指加密和解密使用相同的密钥。如下所示:
AES 代表“高级加密标准”,密钥长度为128、192 或256。它取代了DES算法,安全强度高,性能好,而且部分硬件经过专门优化,使其成为非常流行、应用最广泛的对称加密算法。
ChaCha20 是Google 设计的另一种加密算法,密钥长度固定为256 位,曾经在移动客户端上常见,但现在还添加了AES 硬件优化。它没有任何明显的优点,但仍然是一个很好的算法。
非对称加密
非对称加密对应于一对称为私钥和公钥的密钥,并且需要使用私钥加密并使用公钥解密。用于解密的私钥。如下所示:
尽管对称加密似乎可以实现完美的机密性,但存在一个主要问题。这就是所谓的“密钥交换”以及如何安全地将密钥传递给对方。
这是因为对称加密算法只要你有密钥就可以解密。如果您与网站约定的密钥在传输过程中被黑客窃取,黑客就可以随意解密发送和接收的数据,通信过程不再保密。
我怎么解决这个问题?
你可能会认为“只要加密密钥然后发送即可”。然而,发送“密钥加密密钥”却成了一个新问题。这就好比“鸡生蛋,蛋生鸡”一样,可以无限递归。仅使用对称加密算法是绝对不可能解决密钥交换问题的。
这就是非对称加密(也称为公钥加密算法)发挥作用的地方。
有两把钥匙,一把称为“公钥”,另一把称为“私钥”。两个密钥不同且“不对称”。公钥可以公开给任何人使用,但私钥必须严格保密。
公钥和私钥具有特殊的“单向”属性:两者都可以用于加密和解密,但公钥只能用私钥解密。加密后的公钥。
非对称加密可以解决“密钥交换”问题。网站对私钥保密,并自愿在网上分发公钥。要登录网站,您只需使用公钥对其进行加密即可。密文只能由私钥的所有者解密。黑客无法解密密文,因为他没有私钥。
设计非对称加密算法比对称算法困难得多。 TLS 只有几种类型:DH、DSA、RSA 和ECC。
RSA 也许是最著名的,大致与非对称加密同义,其安全性基于称为“整数分解”的数学问题,其中使用两个非常大的素数的乘积作为生成密钥的材料。 使用。从公钥推导出私钥是非常困难的。十年前,RSA 密钥的建议长度为1024,但随着计算机计算能力的进步,现在人们普遍认为1024 不安全,至少需要2048 位。 ECC(Elliptic Curve Cryptography)是非对称密码学中的一颗“新星”,基于“椭圆曲线离散对数”的数学问题,利用特定的曲线方程和基点生成子算法ECDHE 。用于密钥交换,ECDSA 用于数字签名。与RSA相比,ECC在安全强度和性能方面具有明显的优势。 160 位ECC 相当于1024 位RSA,224 位ECC 相当于2048 位RSA。较短的密钥需要较少的相应计算、内存和带宽消耗,从而提高了加密和解密性能,使其对当今的移动互联网非常有吸引力。
对称加密的优点是计算速度较快,缺点是密钥无法在互联网环境下安全地发送给对方。非对称加密的优点是能够安全地将公钥传递给对方,但速度较慢。
看到这里,你是否认为可以放弃对称加密,只使用非对称加密来保证机密性呢?
这里,TLS结合了对称加密和非对称加密,两者优势互补,能够实现高效的加解密和安全的密钥交换。事实上,坦率地说,这很容易。
在通信开始时使用RSA或ECDHE等非对称算法,首先解决密钥交换问题。
然后使用随机数生成对称算法中使用的“会话密钥”,然后使用公钥对其进行加密。会话密钥很短,通常只有16 或32 字节,因此稍微慢一点是可以的。
当对方获得密文后,用自己的私钥解密,得到会话密钥。这样双方就实现了对称密钥的安全交换,以后将不再使用非对称加密,而改用对称加密。
这样,混合加密就解决了对称加密算法的密钥交换问题,充分实现了兼顾安全性和性能的保密性。
然而,这只是“千里”征程的第一步。当前的通信并不完全安全,完整性、身份认证和不可否认性等功能尚未实现。
数字签名与证书
黑客无法获取会话密钥,也无法解密密文,但他或她可以通过窃听收集足够的密文,并尝试在将其发送到网站之前对其进行修改和重构。由于没有完整性保证,服务器只能“接受全部”,通过服务器的响应可以获得进一步的线索,最终可以解密明文。
此外,黑客还可以伪造身份并暴露公钥。如果您获得伪造的公钥,混合加密就会被完全破解。你以为自己正在与“某人”通信,而实际上网线的另一端有黑客,在“安全”的通信过程中窃取了银行卡号、密码等敏感信息。
因此,要实现真正的安全,必须在基础上增加保密性、完整性、身份认证等功能。
摘要算法
实现一致性的主要手段是摘要算法,也称为散列函数或散列函数。
摘要算法可以粗略地理解为一种特殊的压缩算法,可以将任意长度的数据“压缩”成唯一的固定长度的“摘要”字符串,类似于为该数据部分生成一个数值。 “指纹”。
从另一个角度来看,摘要算法是一种特殊的“单向”加密方法,它只有算法,无法解密加密数据,也无法从摘要中推导出原文。
由于汇总算法实际上是将数据从“大空间”映射到“小空间”,因此它们会受到“碰撞”(也称为碰撞),就像真实的指纹一样。对应相同摘要的原始文本。一个好的摘要算法必须能够“承受碰撞”并最大限度地减少碰撞发生的可能性。
TLS 中还使用了汇总算法来生成伪随机数(PRF,伪随机数),因为输入具有“单向性”和“雪崩效应”,因此输入的微小差异可能会导致输出发生较大变化。将会完成。功能)。
您在日常工作中可能听说过或使用过MD5(消息摘要5)和SHA-1(安全哈希算法1)。这是两种最常用的摘要算法,可以生成16 和20 字节的长度。抽象的。然而,这两种算法的安全强度较低,并且由于不够安全而被禁止在TLS中使用。
当前的TLS 建议是SHA-2,它是SHA-1 的后继者。
SHA-2实际上是一组摘要算法的总称,常用的有SHA224、SHA256和SHA384,它们可以产生28字节、32字节和48字节的摘要。每个。
完整性
摘要算法确保“数字摘要”与原文完全等同。因此,只要在原文后面加上摘要,就可以保证数据的完整性。
例如,发送消息“发送1000元”并添加SHA-2摘要。网站收到消息后,还会计算消息摘要并比较两个“指纹”。如果它们匹配,则意味着消息完整、可靠且未被更改。
如果黑客改变了中间的一个标点符号,摘要就会完全不同,网站通过计算和比较就会知道该消息已被篡改,变得不可靠。
然而,摘要算法并不是秘密。当以明文形式发送时,黑客可以修改消息并更改摘要,但网站无法辨别其完整性。
因此,真正的完整性必须建立在机密性的基础上,并且会话密钥用于在混合密码系统中对消息和摘要进行加密,以便黑客无法学习和操纵明文。
有一个术语称为哈希消息身份验证代码(HMAC)。
数字签名
加密和摘要算法的结合使通信过程更加安全。但是这里还有一个漏洞,那就是通信的两个端点。
正如一开始提到的,黑客可以将自己伪装成网站来窃取信息。此外,他还可以冒充您并向无法验证您身份的网站发送付款、转账和其他消息,您的钱可能会被盗。
实际的身份验证手段是签名和印章。通过在一张纸上签名或盖章,您可以证明该文件是由您而不是其他人签发的。
这里,利用非对称加密的“私钥”和摘要算法实现“数字签名”,同时实现“身份认证”和“不可否认性”。
数字签名的原理其实很简单。以前使用的是公钥加密和私钥解密。
但非对称加密的效率太低,私钥只加密原文的摘要,减少了计算量,而且得到的数字签名也很小,更容易存储和传输。
签名和公钥一样,是完全公开的,任何人都可以获得。然而,这个签名只能使用与私钥对应的公钥来解密。通过获取摘要并将其与原始文本进行比较以验证其完整性,您可以证明该消息确实是您发送的,类似于签名。文档。
刚才提到的两个动作还有一个特殊的术语,叫做“签名”和“签名验证”。
只要用户和网站交换公钥,就可以使用签名和签名验证来验证消息的真实性。私钥是秘密的,黑客无法伪造签名,从而知道通信双方的身份。有保证。
例如,使用您的私钥对消息“我是小敏”进行签名。网站收到后,使用公钥验证签名,并使用私钥对消息“我是宝”进行签名,以确认身份确定。收到后,您可以使用该公钥进行验证。这可以让你和网站都知道对方不是假的,以后可以使用混合加密进行安全通信。
数字证书和 CA
到目前为止,对称加密、非对称加密和摘要算法的结合已经很完美了,对吧?
不,这里还有一个“公钥信任”问题。由于公钥可以由任何人发布,因此仍然无法防止黑客伪造公钥,或者无法确定公钥是您的还是其他人的。
这就像“推了一个葫芦,然后再把它举起来”。安全是一件非常复杂的事情,“一个联系会导致另一个联系”。
可以采用类似密钥交换的方法来解决公钥认证问题,并使用其他私钥对公钥进行签名。这显然属于“无限递归”。但这一次其实是没有办法解决的。要结束这种“死亡循环”,我们需要引入“外部力量”,找到一个公认的、值得信赖的第三方作为“信任的起点和递归的终点”。建立信任的公钥链。
这个“第三方”就是我们常说的CA(证书颁发机构)。这就像网络世界中的公安部、教育部或公证中心一样,对每个公钥进行签名并创建自己的签名,以确保公钥不可伪造且值得信赖。某些形式的CA 公钥签名认证不仅包括将公钥与所有者的身份简单地联系起来,还包括序列号、用途、颁发者、有效期等。这些都被输入到包中。它通过签名来充分证明与公钥相关的各种信息,形成“数字证书”(certificate)。
世界上只有少数几家知名的CA,例如DigiCert、VeriSign、Entrust 和Let’s Encrypt。他们颁发的证书分为三种类型:DV、OV、EV。区别在于认证程度。可靠性。
DV很烂,只能在域名层面可信,没有人知道背后是谁。 EV 是最高的,经过法律和审计的严格验证,以证明网站所有者的身份(您会在浏览器的地址栏中看到公司名称,例如Apple 或GitHub 网站)。
但CA 如何证明自己呢?
这仍然是一个信任链问题。较小的CA 可以拥有较大的CA 进行签名和认证,但链末端的根CA 只能证明自己。这称为“自签名证书”或“根证书”证书。你必须相信它。否则,整个证书信任链将无法前进。
有了这个证书系统,操作系统和浏览器都内置了各大CA的根证书,上网时,只要服务器在发送证书,就可以验证签名并跟踪证书链。 ) 逐层验证,直至找到根证书。您可以确定该证书是可信的,并且里面的公钥也是可信的。
证书制度的弱点
证书系统(PKI,公钥基础设施)是当今整个网络世界的安全基础,但没有绝对的安全,也有弱点,关键词就是“信任”。
如果CA犯了错误或者被欺骗而颁发了虚假证书,那么即使证书是真实的,它所代表的网站也将是假的。
还有一些更危险的情况,即CA 已被黑客破坏或被恶意破坏。这是因为CA(如根证书)是信任源,整个信任链中的所有证书都不能被信任。
这两件事并不“耸人听闻”,而且以前确实发生过。因此,我们需要给证书系统添加一些补丁。
在第一类中,开发了CRL(证书吊销列表)和OCSP(在线证书状态协议)以确保及时吊销有问题的证书。
第二种,涉及的证书太多,操作系统或浏览器只能“硬件”root、撤销对CA的信任、将CA“列入黑名单”。这将被认为是不安全的。
HTTPS 建立连接
当我在浏览器地址栏中键入以“https”开头的URI 并按Enter 时会发生什么?
浏览器首先从URI 中提取协议名称和域名。因为协议名称是“https”,所以浏览器知道端口号是默认的443。然后它使用DNS解析域名并获取目标的IP地址。然后可以使用三向握手建立TCP。与网站的连接。
使用HTTP 协议,一旦建立连接,浏览器就会发送请求消息。然而,我们现在使用HTTPS协议,在发送和接收HTTP消息之前,需要另一个“握手”过程来通过TCP建立安全连接。
这个“握手”过程与TCP类似。如果您理解了这一点,您就可以自信地说您已经掌握了HTTPS。
TLS 协议的组成
在讨论TLS握手之前,我们先简单介绍一下TLS协议的结构。
TLS 包含多个子协议,可以被视为具有不同角色的多个模块。最常用的是记录协议、报警协议、握手协议和密码规范协议。
记录
协议(Record Protocol)规定了 TLS 收发数据的基本单位:记录(record)。它有点像是 TCP 里的 segment,所有的其他子协议都需要通过记录协议发出。但多个记录数据可以在一个 TCP 包里一次性发出,也并不需要像 TCP 那样返回 ACK。警报协议(Alert Protocol)的职责是向对方发出警报信息,有点像是 HTTP 协议里的状态码。比如,protocol_version 就是不支持旧版本,bad_certificate 就是证书有问题,收到警报后另一方可以选择继续,也可以立即终止连接。握手协议(Handshake Protocol)是 TLS 里最复杂的子协议,要比 TCP 的 SYN/ACK 复杂的多,浏览器和服务器会在握手过程中协商 TLS 版本号、随机数、密码套件等信息,然后交换证书和密钥参数,最终双方协商得到会话密钥,用于后续的混合加密系统。最后一个是变更密码规范协议(Change Cipher Spec Protocol),它非常简单,就是一个“通知”,告诉对方,后续的数据都将使用加密保护。那么反过来,在它之前,数据都是明文的。下面的这张图简要地描述了 TLS 的握手过程,其中每一个“框”都是一个记录,多个记录组合成一个 TCP 包发送。所以,最多经过两次消息往返(4 个消息)就可以完成握手,然后就可以在安全的通信环境里发送 HTTP 报文,实现 HTTPS 协议。
ECDHE 握手过程
刚才你看到的是握手过程的简要图,又画了一个详细图,下面我就用这个图来仔细剖析 TLS 的握手过程。
在 TCP 建立连接之后,浏览器会首先发一个“Client Hello”消息,也就是跟服务器“打招呼”。里面有客户端的版本号、支持的密码套件,还有一个随机数(Client Random),用于后续生成会话密钥。
Handshake Protocol: Client HelloVersion: TLS 1.2 (0x0303)Random: 1cbf803321fd2623408dfe…Cipher Suites (17 suites)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)这个的意思就是:“我这边有这些这些信息,你看看哪些是能用的,关键的随机数可得留着。”复制代码
作为“礼尚往来”,服务器收到“Client Hello”后,会返回一个“Server Hello”消息。把版本号对一下,也给出一个随机数(Server Random),然后从客户端的列表里选一个作为本次通信使用的密码套件,在这里它选择了“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384”。
Handshake Protocol: Server HelloVersion: TLS 1.2 (0x0303)Random: 0e6320f21bae50842e96…Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)这个的意思就是:“版本号对上了,可以加密,你的密码套件挺多,我选一个最合适的吧,用椭圆曲线加 RSA、AES、SHA384。我也给你一个随机数,你也得留着。”复制代码
然后,服务器为了证明自己的身份,就把证书也发给了客户端(Server Certificate)。
接下来是一个关键的操作,因为服务器选择了 ECDHE 算法,所以它会在证书后发送“Server Key Exchange”消息,里面是椭圆曲线的公钥(Server Params),用来实现密钥交换算法,再加上自己的私钥签名认证。
Handshake Protocol: Server Key ExchangeEC Diffie-Hellman Server ParamsCurve Type: named_curve (0x03)Named Curve: x25519 (0x001d)Pubkey: 3b39deaf00217894e…Signature Algorithm: rsa_pkcs1_sha512 (0x0601)Signature: 37141adac38ea4…这相当于说:“刚才我选的密码套件有点复杂,所以再给你个算法的参数,和刚才的随机数一样有用,别丢了。为了防止别人冒充,我又盖了个章。”复制代码
之后是“Server Hello Done”消息,服务器说:“我的信息就是这些,打招呼完毕。”
这样第一个消息往返就结束了(两个 TCP 包),结果是客户端和服务器通过明文共享了三个信息:Client Random、Server Random 和 Server Params。
客户端这时也拿到了服务器的证书,那这个证书是不是真实有效的呢?
这就要用到第 25 讲里的知识了,开始走证书链逐级验证,确认证书的真实性,再用证书公钥验证签名,就确认了服务器的身份:“刚才跟我打招呼的不是骗子,可以接着往下走。”
然后,客户端按照密码套件的要求,也生成一个椭圆曲线的公钥(Client Params),用“Client Key Exchange”消息发给服务器。
Handshake Protocol: Client Key Exchange EC Diffie-Hellman Client Params Pubkey: 8c674d0e08dc27b5eaa…现在客户端和服务器手里都拿到了密钥交换算法的两个参数(Client Params、Server Params),就用 ECDHE 算法一阵算,算出了一个新的东西,叫“Pre-Master”,其实也是一个随机数。
至于具体的计算原理和过程,因为太复杂就不细说了,但算法可以保证即使黑客截获了之前的参数,也是绝对算不出这个随机数的。
现在客户端和服务器手里有了三个随机数:Client Random、Server Random 和 Pre-Master。用这三个作为原始材料,就可以生成用于加密会 话的主密钥,叫“Master Secret”。而黑客因为拿不到“Pre-Master”,所以也就得不到主密钥。
为什么非得这么麻烦,非要三个随机数呢?
这就必须说 TLS 的设计者考虑得非常周到了,他们不信任客户端或服务器伪随机数的可靠性,为了保证真正的“完全随机”“不可预测”,把三个不可靠的随机数混合起来,那么“随机”的程度就非常高了,足够让黑客难以猜测。
你一定很想知道“Master Secret”究竟是怎么算出来的吧,贴一下 RFC 里的公式:
master_secret = PRF(pre_master_secret, “master secret”,ClientHello.random + ServerHello.random)这里的“PRF”就是伪随机数函数,它基于密码套件里的最后一个参数,比如这次的 SHA384,通过摘要算法来再一次强化“Master Secret”的随机性。复制代码
主密钥有 48 字节,但它也不是最终用于通信的会话密钥,还会再用 PRF 扩展出更多的密钥,比如客户端发送用的会话密钥(client_write_key)、服务器发送用的会话密钥(server_write_key)等等,避免只用一个密钥带来的安全隐患。
有了主密钥和派生的会话密钥,握手就快结束了。客户端发一个“Change Cipher Spec”,然后再发一个“Finished”消息,把之前所有发送的数据做个摘要,再加密一下,让服务器做个验证。
意思就是告诉服务器:“后面都改用对称算法加密通信了啊,用的就是打招呼时说的 AES,加密对不对还得你测一下。”
服务器也是同样的操作,发“Change Cipher Spec”和“Finished”消息,双方都验证加密解密 OK,握手正式结束,后面就收发被加密的 HTTP 请求和响应了。
RSA 握手过程
整个握手过程可真是够复杂的,但你可能会问了,好像这个过程和其他地方看到的不一样呢?
刚才说的其实是如今主流的 TLS 握手过程,这与传统的握手有两点不同。
第一个,使用 ECDHE 实现密钥交换,而不是 RSA,所以会在服务器端发出“Server Key Exchange”消息。
第二个,因为使用了 ECDHE,客户端可以不用等到服务器发回“Finished”确认握手完毕,立即就发出 HTTP 报文,省去了一个消息往返的时间浪费。这个叫“TLS False Start”,意思就是“抢跑”,和“TCP Fast Open”有点像,都是不等连接完全建立就提前发应用数据,提高传输的效率。
这里我也画了个图。
大体的流程没有变,只是“Pre-Master”不再需要用算法生成,而是客户端直接生成随机数,然后用服务器的公钥加密,通过“Client Key Exchange”消息发给服务器。服务器再用私钥解密,这样双方也实现了共享三个随机数,就可以生成主密钥。
双向认证
到这里 TLS 握手就基本讲完了。
不过上面说的是“单向认证”握手过程,只认证了服务器的身份,而没有认证客户端的身份。这是因为通常单向认证通过后已经建立了安全通信,用账号、密码等简单的手段就能够确认用户的真实身份。
但为了防止账号、密码被盗,有的时候(比如网上银行)还会使用 U 盾给用户颁发客户端证书,实现“双向认证”,这样会更加安全。
双向认证的流程也没有太多变化,只是在“Server Hello Done”之后,“Client Key Exchange”之前,客户端要发送“Client Certificate”消息,服务器收到后也把证书链走一遍,验证客户端的身份。
作者:huansky
来源:https://www.cnblogs.com/huansky/p/13977181.html
原创文章,作者:共创,如若转载,请注明出处:https://www.sudun.com/ask/94352.html