SSL如何工作?我只是意识到我们在这里实际上没有明确的答案,这值得一谈。

我想从以下方面查看详细信息:


协议的高级描述。
密钥交换的工作方式。
如何强制执行真实性,完整性和机密性。
拥有CA的目的是什么,以及它们如何颁发证书。
所涉及的任何重要技术和标准(例如PKCS)的详细信息。


评论

四年后,我现在用Python编写了一个有效的TLS实现,作为规范正确性测试的基础。答案是官方规范的绝佳参考。

#1 楼

通用SSL(及其后继TLS)是一种直接在TCP之上运行的协议(尽管也有基于数据报的协议的实现,例如UDP)。这样,高层协议(例如HTTP)可以保持不变,同时仍提供安全连接。在SSL层下,HTTP与HTTPS相同。
正确使用SSL / TLS时,攻击者可以在电缆上看到的是您所连接的IP和端口,大致发送的数据量以及发送的数据使用加密和压缩。他还可以终止连接,但双方都知道连接已被第三方中断。
在典型用法中,攻击者还可以弄清您要连接的主机名(但不是URL的其余部分):尽管HTTPS本身不公开主机名,但是您的浏览器通常需要首先发出DNS请求,以查找将请求发送到的IP地址。
协议的高级描述
建立TCP连接后,客户端开始SSL握手。客户端(可以是浏览器,也可以是任何其他程序,例如Windows Update或PuTTY)发送许多规范:

它正在运行哪个版本的SSL / TLS,
它想要使用的密码套件,以及它想要使用的压缩方式。客户的选项(如果支持),并选择一种压缩方法。
完成基本设置后,服务器将发送其证书。客户端本身或客户端信任的一方必须信任此证书。例如,如果客户端信任GeoTrust,则客户端可以信任来自Google.com的证书,因为GeoTrust用密码对Google的证书进行了签名。
验证证书并确定此服务器确实是他声称的身份(而不是中间的人)后,交换了密钥。根据所选的密码套件,它可以是公用密钥,“ PreMasterSecret”或根本不包含任何内容。服务器和客户端现在都可以计算对称加密密钥,而不是PKE。客户端告诉服务器,从现在开始,所有通信将被加密,并向服务器发送加密并经过身份验证的消息。
服务器验证MAC(用于身份验证)正确并且消息可以被验证。正确解密。然后,它返回一条消息,客户端也将对其进行验证。
现在握手已完成,并且两个主机可以安全地通信。有关更多信息,请参见technet.microsoft.com/zh-cn/library/cc785811和en.wikipedia.org/wiki/Secure_Sockets_Layer。
要关闭连接,请使用close_notify'alert'。如果攻击者试图通过完成TCP连接(注入FIN数据包)来终止连接,则双方都将知道该连接被不当终止。但是,连接并不能因此受到破坏,而只是中断即可。
更多详细信息
为什么您可以通过信任GeoTrust来信任Google.com?为了证明其身份并确保它不是攻击者,您必须具有服务器的公钥。但是,您几乎无法存储地球上所有网站的所有密钥,数据库将非常庞大,并且必须每小时运行一次更新!
解决方案是证书颁发机构,简称CA。当您安装操作系统或浏览器时,可能会附带一系列受信任的CA。该列表可以随意修改;您可以删除不信任的人,添加其他人,甚至创建自己的CA(尽管您将是唯一信任此CA的人,因此对于公共网站来说它用处不大)。在此CA列表中,还存储了CA的公钥。
当Google的服务器向您发送其证书时,它还会提到该证书是由GeoTrust签名的。如果您信任GeoTrust,则可以(使用GeoTrust的公钥)验证GeoTrust是否确实签署了服务器的证书。要自己签署证书,您需要专用密钥,只有GeoTrust知道。这样,攻击者便无法自己签署证书并错误地声称自己是Google.com。如果证书仅被修改了一点,该符号将是不正确的,并且客户端将拒绝它。
因此,如果我知道公钥,则服务器可以证明其身份?通常,公钥加密,而私钥解密。使用服务器的公钥对消息进行加密,然后将其发送,如果服务器可以重复发送原始消息,则仅证明它在不泄露密钥的情况下获得了私钥。
这就是为什么如此重要能够信任公钥:任何人都可以生成私钥/公钥对,也可以是攻击者。您不想最终使用攻击者的公钥!
如果您信任的CA之一遭到破坏,则攻击者可以使用被盗的私钥为他们喜欢的任何网站签名证书。当攻击者可以向您的客户端发送伪造的证书,该证书由他自己使用您信任的CA的私钥签名时,您的客户端就不知道该公钥是伪造的,并使用被盗的私钥签名。
但是CA可以使我信任他们想要的任何服务器!
是的,这就是信任的来源。您必须信任CA不能随意制作证书。但是,当像Microsoft,Apple和Mozilla这样的组织信任CA时,该CA必须进行审核。另一个组织会定期检查它们,以确保一切仍在按规则进行。
只有在注册人可以证明自己拥有为其颁发证书的域时,才可以颁发证书。
此MAC用于消息身份验证是什么?
每个消息都使用所谓的消息身份验证码(简称MAC)签名。如果我们在密钥和哈希密码上达成共识,则可以验证我的消息来自我,也可以验证你的消息来自你。示例”,我可以计算出MAC“ 58393”。当我将带有MAC的消息发送给您(您已经知道密钥)时,您可以执行相同的计算,并将计算出的MAC与我发送的MAC相匹配。
攻击者可以修改消息,但不能知道钥匙。他无法计算出正确的MAC,您将知道消息是不真实的。
通过在计算MAC时添加序列号,可以消除重放攻击。 SSL会这样做。
您说客户端发送了一个密钥,然后将其用于设置对称加密。阻止攻击者使用它的原因是什么?
服务器的公钥可以使用它。由于我们已经验证了公用密钥确实属于服务器,而没有其他人,因此我们可以使用公用密钥对密钥进行加密。服务器收到此消息后,可以使用私钥对其进行解密。
这也是为什么密钥大小很重要的原因:公钥和私钥越大,破解客户端发送给服务器的密钥就越难。 >如何破解SSL
总结:

请尝试如果用户忽略证书警告;
应用程序可能会从未加密的通道(例如HTTP)加载数据,这可能会被篡改with;
可以修改提交到HTTPS的不受保护的登录页面,以便提交到HTTP;
未打补丁的应用程序可能容易受到BEAST和CRIME等漏洞的攻击;
重新使用其他方法,例如物理攻击;
利用诸如消息长度和形成消息所需的时间之类的副渠道;
等待量子攻击。

另请参阅:一种具有多种针对攻击的向量的方案Ivan Ristic的SSL(png)
详细说明:
没有简单直接的方法;正确完成后,SSL是安全的。攻击者可以尝试如果用户忽略证书警告,那将立即破坏安全性。当用户执行此操作时,攻击者不需要来自CA的私钥来伪造证书,他只需要发送自己的证书即可。
另一种方式是通过应用程序中的缺陷(服务器-或客户端)。一个简单的例子是在网站中:如果网站使用的一种资源(例如图像或脚本)是通过HTTP加载的,则无法再保证机密性。即使浏览器在从安全页面(源)请求非安全资源时未发送HTTP Referer标头,窃听流量的人仍然有可能猜测您的访问来源;例如,如果他们知道在一个页面上使用X,Y和Z图像,那么当他们看到浏览器一次请求这三个图像时,他们可以猜测您正在访问该页面。此外,在加载Javascript时,整个页面可能会受到影响。攻击者可以执行该页面上的任何脚本,例如修改银行交易的对象。
发生这种情况(通过HTTP加载资源)时,浏览器会发出混合内容警告:Chrome,Firefox, Internet Explorer 9
HTTP的另一个技巧是当登录页面不受保护并且提交到https页面时。开发人员可能会想:“太好了,现在我可以节省服务器负载,并且密码仍然以加密方式发送!”问题是sslstrip,该工具修改了不安全的登录页面,以便将其提交到某处,以便攻击者可以读取它。
过去几年中还发生了各种攻击,例如TLS重新协商漏洞,sslsnniff ,BEAST和最近的CRIME。但是,所有常用的浏览器都受到保护,免受所有这些攻击,因此,如果您运行的是最新的浏览器,则这些漏洞没有风险。
最后但并非最不重要的一点是,您可以使用其他方法来获取SSL拒绝获取的信息。如果您已经可以看到并篡改用户的连接,则用键盘记录程序替换他/她的.exe下载文件之一,或者仅仅用物理手段攻击该人可能并不难。密码术可能相当安全,但是人为和人为错误仍然是一个薄弱因素。根据Verizon的这篇论文,10%的数据泄露涉及物理攻击(请参阅第3页),因此,一定要牢记这一点。

评论


我会对对称密钥的“密钥交换”有更多的解释感兴趣。具有数据包嗅探器的人无法访问怎么办。

– Yeehosef
13年4月3日,11:14

@Yehosef好问题!我忘了在回答中解释这一点。环顾四周,事实证明实际上存在一个专门针对此问题:security.stackexchange.com/q/6290/10863

–吕克
2013年4月6日19:05

@Iwazaru从第一天开始,所有CA都会这样做。证书的目的是提供给定域的公钥,对其进行签名以证明它确实是该域的正确密钥。让我们加密完全按照它应该做的:验证您对域的所有权,并在可以证明的情况下(使用密钥)签署证书。现在,几乎每个浏览器都信任“让我们加密”的每个人都将信任该证书。

–吕克
16年4月8日在23:30

呃没有。 TLS确实只是在TCP之上实现的。

–tialaramex
17年2月2日,0:32

发现了这个图形化的SSL握手过程,非常清楚。

–罗伊(Roy Ling)
17年6月8日在10:55

#2 楼

由于SSL的一般概念已经包含在其他一些问题中(例如,这个问题和那个问题),因此这次我将详细介绍。细节很重要。这个答案有些冗长。

历史记录

SSL是一个历史悠久且有多个版本的协议。 Netscape最初的原型来自Netscape,当时他们正在开发其旗舰浏览器Netscape Navigator的第一个版本(该浏览器在“浏览器大战”的早期就被Mosaic淘汰,尽管与新竞争者竞争,该马赛克仍在肆虐)。版本1从未公开,因此我们不知道它的外观。草案中描述了SSL版本2,可以在此处阅读。它具有许多缺点,其中一些缺点相当严重,因此不建议使用,并且较新的SSL / TLS实现不支持它(默认情况下,较旧的状态为停用)。除了作为偶尔的参考,我将不再谈论SSL版本2。

SSL版本3(我将其称为“ SSLv3”)是一种增强的协议,至今仍然有效,并得到广泛支持。尽管仍是Netscape Communications(或如今的所有人)的财产,但该协议已作为“历史RFC”(RFC 6101)发布。同时,该协议已经标准化,并使用了新名称以避免法律问题。到目前为止,已经生产了三个版本的TLS,每个版本都有其专用的RFC:TLS 1.0,TLS 1.1和TLS 1.2。它们在内部和SSLv3之间非常相似,以至于实现可以轻松支持SSLv3和所有三个TLS版本,而至少有95%的代码是通用的。在内部,所有版本仍由具有major.minor格式的版本号指定;然后,SSLv3为3.0,而TLS版本分别为3.1、3.2和3.3。因此,难怪TLS 1.0有时也被称为SSL 3.1(这也不是不正确的)。 SSL 3.0和TLS 1.0仅在一些细节上有所不同。
TLS 1.1和1.2尚未得到广泛支持,尽管这样做有一定的动力,因为可能存在缺陷(请参阅下文中的“ BEAST攻击”)。 SSLv3和TLS 1.0在任何地方都受支持(即使IE 6.0也知道它们)。

上下文

SSL旨在为任意数据提供安全的双向隧道。考虑TCP,它是通过Internet发送数据的众所周知的协议。 TCP通过IP“数据包”工作,并为字节提供双向隧道。它适用于每个字节值,并将它们发送到两个可以同时运行的流中。 TCP处理将数据拆分为数据包,对其进行确认,将它们重新组合成正确顺序的艰苦工作,同时删除重复数据并丢失丢失的数据包。从使用TCP的应用程序的角度来看,只有两个流,并且数据包是不可见的。特别是,流不会拆分为“消息”(如果应用希望接收消息,则应由应用程序采用自己的编码规则,而这正是HTTP所要做的)。

TCP是在出现“事故”的情况下是可靠的,即由于不稳定的硬件,网络拥塞,使用智能手机的人走出给定基站范围而导致的传输错误以及其他非恶意事件。但是,对传输介质有某种访问权限的恶意对象(“攻击者”)可以读取所有已传输的数据和/或有意地更改它,而TCP则无法防止这种情况。因此,SSL。

SSL假定它在类似TCP的协议上工作,该协议提供了可靠的流。 SSL不会实现丢失数据包之类的重新发送。攻击者应该有权以不可避免的方式完全破坏通信(例如,他可以切断电缆),因此SSL的工作是:




检测更改(攻击者一定不能无声地更改数据);
确保数据机密性(攻击者不得获取所交换数据的知识)。

SSL在很大程度上(但不是绝对的)实现了这些目标。

记录

SSL是分层的,底层是记录协议。 SSL隧道中发送的所有数据都将拆分为记录。通过导线(底层的TCP套接字或类似TCP的介质),记录如下所示:


HH V1:V2 L1:L2数据





HH是一个单字节,指示记录中的数据类型。定义了四种类型:change_cipher_spec(20),alert(21),握手(22)和application_data(23)。V1: V2是协议版本,超过两个字节。对于当前定义的所有版本,V1的值为0x03,而SSLv3的V2的值为0x00,TLS 1.0的值为0x01,TLS 1.1的值为0x02,TLS 1.2的值为0x03。

L1: L2data的长度字节(使用big-endian约定:长度为256 * L1 + L2)。 data的总长度不能超过18432个字节,但实际上它甚至不能达到该值。

因此,一条记录有一个5字节的标头,其后最多18 kB的数据。在data上应用对称加密和完整性检查。发出记录时,发送方和接收方都应就当前使用的加密算法以及使用的密钥达成一致。该协议是通过握手协议获得的,该协议将在下一部分中介绍。

在详细信息上,记录的建立也是如此:


最初,有一些压缩要传输的字节;这些是应用程序数据或其他某种字节。此有效负载最多包含16384个字节,但可能更少(长度为0的有效负载是合法的,但事实证明Internet Explorer 6.0完全不喜欢它)。
然后,使用当前商定的任何压缩算法对有效负载进行压缩。压缩是有状态的,因此可能取决于先前记录的内容。在实践中,压缩要么是“空”(根本没有压缩),要么是“ Deflate”(RFC 3749),由于最近的CRIME攻击,后者目前是有礼貌的,但已在Web上下文中牢固地显示了退出之门。压缩旨在缩短数据,但在某些不利情况下(由于信鸽原理),必须将其略微扩展。 SSL允许最多扩展1024个字节。当然,空值压缩永远不会扩大(但也不会缩短)。如果实现良好,则Deflate最多可扩展10个字节。
然后保护压缩的有效载荷,以防止更改和加密。如果当前的加密和完整性算法为“空”,则此步骤为空操作。否则,将添加MAC,然后进行一些填充(取决于加密算法),并对结果进行加密。这些步骤再次引起扩展,SSL标准将扩展限制为1024个额外的字节(结合压缩步骤中的最大扩展,这使我们达到18432个字节,必须在其中添加5个字节的标头)。

MAC通常是具有常见哈希函数之一的HMAC(主要是MD5,SHA-1或SHA-256)(对于SSLv3,这不是“真正的” HMAC,而是非常相似的,并且据我们所知) ,与HMAC一样安全)。加密将使用CBC模式下的分组密码或RC4流密码。注意,从理论上讲,可以采用其他类型的模式或算法,例如,结合了加密和完整性检查的这些漂亮的模式之一;甚至还有一些RFC。但是,实际上,部署的实现尚不了解这些,因此HMAC和CBC也可以。至关重要的是,首先要计算MAC并将其附加到数据中,然后对结果进行加密。这是MAC然后加密的,实际上不是一个好主意。 MAC是根据(压缩的)有效负载和序列号的连接计算的,因此勤奋的攻击者可能不会交换记录。

握手

握手是一种协议在记录协议中播放。其目标是建立用于记录的算法和密钥。它由消息组成。每个握手消息以一个四字节的标头开始,一个字节描述消息的类型,然后是三个字节的消息长度(big-endian约定)。然后,将使用标记为“握手”类型的记录发送连续的握手消息(每个记录的标题的第一个字节的值为22)。

请注意以下各层:握手消息,由四个组成-byte标头,然后作为记录发送,每个记录也有自己的标头。此外,可以在同一记录内发送几个握手消息,并且给定的握手消息可以拆分为多个记录。从构建握手消息的模块的角度来看,“记录”只是可以在其上发送字节的流。它完全忽略了将流实际分成记录的情况。

完全握手

最初,客户端和服务器“同意”没有MAC和null压缩的null加密。这意味着他们将首先发送的记录将以明文形式发送,并且不受保护。

握手的第一个消息是ClientHello。客户端通过该消息声明其打算执行某些SSL。注意“客户”是一个象征性角色;意思是“首先讲话的党”。碰巧的是,在HTTPS上下文中,即HTTP-in-SSL-in-TCP中,所有这三个层都有“客户端”和“服务器”的概念,并且它们都同意(TCP客户端也是SSL客户端,

ClientHello消息包含:


该客户端希望支持的最大协议版本;
“客户端随机数”(32字节,其中28个字节应该由密码强数字生成器生成);
“会话ID”(如果客户端希望以缩写形式恢复会话握手,请参见下文);
客户端知道的“密码套件”列表,按客户端首选项排序;
客户端知道的压缩算法的列表,按客户端首选项排序;
/>一些可选扩展。

密码套件是一组密码算法的16位符号标识符。例如,TLS_RSA_WITH_AES_128_CBC_SHA密码套件的值为0x002F,表示“记录使用128位密钥使用HMAC / SHA-1和AES加密,并且密钥交换是通过使用服务器的RSA公共密钥加密随机密钥来完成的”。

服务器用ClientHello响应ServerHello,其中包含:


客户端和服务器将使用的协议版本;
“服务器随机”(32个字节,其中28个随机字节);
此连接的会话ID;
将使用的密码套件;
将使用的压缩算法;
(可选)一些扩展。

完整的握手如下所示:

  Client                                               Server

  ClientHello                  -------->
                                                  ServerHello
                                                 Certificate*
                                           ServerKeyExchange*
                                          CertificateRequest*
                               <--------      ServerHelloDone
  Certificate*
  ClientKeyExchange
  CertificateVerify*
  [ChangeCipherSpec]
  Finished                     -------->
                                           [ChangeCipherSpec]
                               <--------             Finished
  Application Data             <------->     Application Data


(此架构已从RFC中无耻地复制了。)

我们看到了ClientHelloServerHello。然后,服务器发送一些其他消息,这些消息取决于密码套件和一些其他参数:



证书:服务器的证书,其中包含其公钥。下面的更多内容。该消息几乎总是发送的,除非密码套件要求没有证书的握手。

ServerKeyExchange:如果证书中的内容不够用,则密钥交换需要一些额外的值。特别是,“ DHE”密码套件使用临时Diffie-Hellman密钥交换,这需要该消息。

CertificateRequest:一条消息,请求客户端也使用自己的证书来标识自己。该消息包含服务器将用于验证客户端证书的信任锚(也称为“根证书”)的名称列表。服务器已完成,客户端现在应该进行对话。

客户端必须以以下方式响应:



证书:客户端证书,如果服务器请求一个。版本之间存在细微的差异(对于SSLv3,客户端没有证书就必须忽略此消息;对于TLS 1.0+,在相同情况下,客户端必须发送带有空证书列表的Certificate消息)。

ClientKeyExchange:实际密钥交换的客户端部分(例如,使用服务器RSA密钥加密的一些随机值)。

CertificateVerify:由客户端在之前的所有握手中计算出的数字签名消息。当服务器请求客户端证书并且客户端已合规时,将发送此消息。这是客户端向服务器证明其确实“拥有”公钥的方式,该公钥已编码在发送的证书中。

然后,客户端发送一条ChangeCipherSpec消息,它不是握手消息:它具有自己的记录类型,因此将以其自己的记录发送。它的内容纯粹是符号性的(值为1的单个字节)。此消息标记了客户端切换到新协商的密码套件和密钥的时间点。来自客户端的后续记录将被加密。

Finished消息是对所有先前的握手消息(来自客户端和服务器)的加密校验和。由于它是在ChangeCipherSpec之后发出的,因此完整性检查和加密也涵盖了它。当服务器接收到该消息并验证其内容时,它将获得证明它确实一直在与同一客户端进行对话的证据。此消息可保护握手免受更改(攻击者无法修改握手消息,但仍正确获取Finished消息)。到此,握手结束,客户端和服务器可以交换应用程序数据(在带有此类标签的加密记录中)。密码套件在服务器手中。礼貌的服务器应该遵循客户端的偏好(如果可能的话),但是它们可以这样做,而有些却可以(例如,作为防止BEAST的一部分)。 br />在完整的握手中,服务器向客户端发送“会话ID”(即一堆最多32个字节)。稍后,客户端可以返回并发送相同的会话ID作为其ChangeCipherSpec的一部分。这意味着客户端仍会记住先前握手中的密码套件和密钥,并希望重用这些参数。如果服务器还记得密码套件和密钥,则它将特定的会话ID复制到其Finished中,然后遵循缩写的握手:

  Client                                                Server

  ClientHello                   -------->
                                                   ServerHello
                                            [ChangeCipherSpec]
                                <--------             Finished
  [ChangeCipherSpec]
  Finished                      -------->
  Application Data              <------->     Application Data


缩短的握手时间更短:消息更少,没有非对称加密业务,最重要的是减少了延迟。 Web浏览器和服务器做了很多事情。典型的Web浏览器将打开具有完整握手的SSL连接,然后为到同一服务器的所有其他连接做简短的握手:它并行打开的其他连接,以及到同​​一服务器的后续连接。确实,典型的Web服务器将在闲置15秒后关闭连接,但是它们会将会话(密码套件和密钥)记住的时间更长(可能长达数小时甚至数天)。

密钥交换

SSL可以使用几种密钥交换算法。这是由密码套件指定的;每个密钥交换算法都可以与某些服务器公钥一起使用。最常见的密钥交换算法为:ClientHello:服务器的密钥为RSA类型。客户端生成一个随机值(“主密码”为48个字节,其中有46个是随机的),并使用服务器的公钥对其进行加密。没有ServerHello

RSA:服务器的密钥为RSA类型,但仅用于签名。实际的密钥交换使用Diffie-Hellman。服务器发送ServerKeyExchange消息,其中包含DH参数(模数,生成器)和新生成的DH公钥;此外,服务器还会对此消息签名。客户端将以DHE_RSA消息作为响应,该消息还包含一个新生成的DH公共密钥。 DH产生“主密码”。

ServerKeyExchange:类似于ClientKeyExchange,但是服务器具有DSS密钥(“ DSS”也称为“ DSA”)。 DSS是仅签名算法。

较少使用的密钥交换算法包括:



DHE_DSS:服务器的密钥为Diffie-Hellman类型(我们正在谈论包含DH密钥的证书)。当RSA专利仍处于活动状态时(这是在上个世纪),它曾经以管理方式(“美国联邦政府强制使用”)“流行”。尽管有官僚作风,但它从未像RSA那样广泛部署。

DHE_RSA:与DH套件类似,但是没有服务器的签名。这是一个无证书的密码套件。通过构造,它很容易受到中间人攻击,因此很少启用。

DH_anon:预共享的密钥密码套件。仅基于对称的密钥交换,建立在预先建立的共享密钥上。

DHE:SRP协议的应用,它是密码认证的密钥交换协议。客户端和服务器就共享机密进行相互认证,该共享机密可以是低熵密码(而PSK需要高熵共享密钥)。很漂亮尚未得到广泛支持。
临时RSA密钥:与PSK类似,但具有新生成的RSA密钥对。由于生成RSA密钥很昂贵,因此这不是一种流行的选择,并且仅被指定为“出口”密码套件的一部分,该套件符合2000年前的美国密码学出口法规(即最多512位的RSA密钥)。如今没有人这样做。
带有椭圆曲线的SRP算法的各种形式。非常时尚。

证书和认证

数字证书是非对称密钥的容器。它们旨在解决密钥分配。即,客户端要使用服务器的公钥。攻击者将尝试使客户端使用攻击者的公钥。因此,客户端必须有一种方法来确保它使用的是正确的密钥。

SSL应该使用X.509。这是证书的标准。每个证书均由证书颁发机构签署。这个想法是客户端固有地知道少数几个CA的公钥(这些是“信任锚”或“根证书”)。使用这些密钥,客户端可以通过已颁发给服务器的证书来验证由CA计算的签名。此过程可以递归扩展:CA可以为另一个CA颁发证书(即,对包含其他CA名称和密钥的证书结构进行签名)。一连串的证书链以根CA开头,以服务器的证书结尾,中间有CA证书,每个证书都相对于先前证书中编码的公钥进行了签名,这毫无疑问是一个证书链。 br />
因此客户端应该执行以下操作:


获取以服务器证书结尾的证书链。服务器的DHE消息应该恰好包含这样的链。

验证链,即验证所有签名和名称以及各种X.509位。另外,客户端应检查链中所有证书的吊销状态,这很复杂且繁琐(Web浏览器现在或多或少都在这样做,但这是最近的发展)。
验证目标服务器名称确实写在服务器的证书中。因为客户端不仅希望使用经过验证的公共密钥,而且还希望使用特定服务器的公共密钥。有关在HTTPS上下文中如何完成此操作的详细信息,请参见RFC2818。

带有X.509证书的认证模型经常被批评,不是真的出于技术理由,而是出于政治经济原因。它将验证能力集中在一些参与者的手中,这些参与者不一定是善意的,或者至少不是总能胜任。一次又一次地发布了针对其他系统的建议(例如Convergence或DNSSEC),但没有一个得到广泛接受(尚未)。

对于基于证书的客户端身份验证,完全取决于服务器来决定与客户证书怎么办(以及与拒绝发送证书的客户怎么办)。在Windows / IIS / Active Directory世界中,客户端证书应包含一个帐户名称作为“用户主体名称”(在证书的“主题替代名称”扩展名中编码);服务器会在其Active Directory服务器中查找它。

再次握手

由于握手只是一些消息,这些消息以当前的加密/压缩约定作为记录发送,因此没有任何事情理论上可以防止SSL客户端和服务器在已建立的SSL连接中进行第二次握手。而且,实际上它是受支持的,并且在实践中会发生。

客户端或服务器随时可以发起新的握手(服务器可以发送DH*消息来触发它,客户端只是发送Certificate)。典型情况如下:


将HTTPS服务器配置为侦听SSL请求。
客户端连接并执行握手。
一旦握手完成后,客户端将发送其“应用数据”,其中包含HTTP请求。在那一刻(仅在那一刻),服务器学习目标路径。到目前为止,服务器尚不知道客户端希望访问的URL(服务器可能已经通过服务器名称指示SSL扩展名获知了目标服务器名称,但这不包括路径)。
在看到路径之后,服务器可以得知这是针对其数据的一部分,该数据应该仅由通过证书验证的客户端访问。但是服务器没有握手请求客户端证书(特别是因为不那么旧的Web浏览器在请求证书时会显示异常弹出窗口,尤其是如果它们没有证书时,因此服务器将避免询问如果没有足够的理由相信客户端拥有证书并知道如何使用证书,则该证书无效。)
因此,服务器触发了一次新的握手,这次请求证书。

我刚才描述的情况有一个有趣的弱点;解决方法请参阅RFC 5746。从概念上讲,SSL仅以“转发”方式传输安全特征。在进行新的握手时,在新握手之前关于客户端的任何已知信息在之后(例如,如果客户端在隧道内发送了良好的用户名和密码)仍然有效,但反之则无效。在上述情况下,在第二次握手的基于证书的身份验证中未涵盖在新握手之前收到的第一个HTTP请求,攻击者可能选择了该请求!不幸的是,某些Web服务器只是假设第二次握手的客户端身份验证扩展到第二次握手之前发送的身份,并且允许攻击者进行一些令人讨厌的欺骗。 RFC 5746尝试解决此问题。

警报

警报消息只是警告和错误消息。它们相当无趣,除非它们可以被某些攻击所破坏(请参阅下文)。

有一条重要的警报消息,称为HelloRequest:这是客户端或服务器希望关闭连接时发送的消息。接收到此消息后,服务器或客户端还必须使用ClientHello进行响应,然后认为隧道已关闭(但该会话仍然有效,并且可以在别有用心的握手中重用)。有趣的是,这些警报消息与所有其他记录一样,都受到加密和MAC的保护。因此,连接关闭由密码保护伞覆盖。数据扩展到传输流的末尾。带有SSLv2的旧HTTP(不具有close_notify)使攻击者可以强制关闭客户端(通常在TCP级别上)进行正常关闭的连接。因此,攻击者可以截断数据而不会被捕获。这是SSLv2的问题之一(可以说是最糟糕的),而SSLv3可以解决此问题。请注意,“现代” HTTP使用“ Content-Length”标头和/或分块编码,即使SSL层允许它也不会受到这种截断的影响。不过,很高兴知道SSL为关闭事件提供了保护。

附件

Stack Exchange应答长度是有限制的,因此对SSL的某些攻击的描述将是另一个答案(此外,我还有一些煎饼要煮)。请继续关注。

评论


SSLv3现在由于其安全漏洞而被贬值。 POODLE攻击。

– Wafeeq
17年8月31日在12:09



@ThomasPornin,这是我在互联网上找到的最好的解释,谢谢!我们是否有机会让您为新的TLS 1.3握手更新它?:)

–穆罕默德·哈菲兹(Mohamed Hafez)
6月29日21:53

#3 楼

在前面的答案中对SSL进行了冗长的介绍之后,让我们来谈谈有趣的东西,即:

SSL攻击

SSL受到了很多攻击,有些攻击基于实施错误,还有其他一些真正的协议弱点。研究文章),SSL也是修复最多的协议之一。它之所以被认为是可靠的,是因为已经在SSL上尝试了所有已知的攻击传输协议的方法,并且在适当的地方对SSL进行了修补。

版本回滚

在在SSLv3的早期,SSLv2仍被广泛使用,因此客户端通常会发送与SSLv2兼容的ClientHello消息,这仅表示也支持SSLv3。然后,服务器将获取提示并以SSLv3 +的方言响应(有关详细信息,请参阅RFC 2246的附录E)。由于SSLv2具有弱点,因此,攻击者的最大利益是安排一个都知道SSLv3的客户端和服务器,但仍然使用SSLv2进行对话。这称为版本回滚攻击。该概念也正式扩展到更高版本。

添加了Kludge以检测回滚尝试。对于从SSLv2的回滚,知道SSLv3 +的客户端应对RSA加密步骤(仅SSLv2仅支持基于RSA的密钥交换)采用特殊填充:在PKCS#1中,应加密的数据应为填充一些随机字节;然后,应该知道SSLv3的客户端将最后八个填充字节中的每一个设置为固定值0x03。然后服务器检查这些字节。如果找到了八个0x03,则很可能尝试了回滚,并且服务器拒绝了该尝试(仅SSLv2的客户端出于运气不足而仅使用255-8的概率使用此类填充字节,因此出现误报)对于回滚到旧版本的SSL / TLS(但不早于SSLv3),

,添加了另一个混合:在48个字节的主密码之前的秘密中,客户端使用服务器的RSA密钥,前两个字节不是随机的,但应等于客户端在其ClientHello消息中首先写入的“最大支持协议版本”。不幸的是,有些客户弄错了,这种纠缠仅适用于基于RSA的密钥交换,因此,防止回滚的保护非常有限。幸运的是,SSLv3 +还具有更强大的防止回滚的保护,这是在构建Finished消息时将握手消息散列在一起。除非“旧版本”太弱以至于攻击者可以在握手本身结束之前完全破坏整个加密,否则这可以防止回滚。这还没有发生(SSLv3仍然相当强大)。

弱密码套件

某些标准密码套件在某种程度上是故意弱的。有:


一些完全不加密的密码套件,仅进行完整性检查,例如TLS_RSA_WITH_NULL_SHA;
一些带有40位加密的密码套件,例如TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5(旨在遵守上个世纪严格的美国出口法规的密码套件-这些法规在比尔·克林顿时代末期已被取消);
一些具有56位加密的密码套件,例如TLS_RSA_WITH_DES_CBC_SHA。使用现有技术可以破坏56位DES,但是对于业余爱好者(即使是无聊的学生,也可以使用几百台大学机器)来说,这仍然有点困难,因此我倾向于将56位DES视为“中等强度”。 br />
这为版本回滚攻击的变种开辟了道路,在该版本中,攻击者迫使客户端和服务器就弱密码套件达成一致,其想法是,攻击者修改了攻击者宣布的密码套件列表。客户。如果所选的密码套件太弱,以至于他可以破坏它以便重新计算显然正确的Finished消息,这对于攻击者是可行的。实际上,SSLv3 +中使用的MAC(即使基于MD5)也足够强大,可以防止这种情况的发生。因此,这里没有实际的担心。另外,我的观点是,当客户端或服务器完全接受使用弱密码套件时,这才是真正的弱点。

默认情况下,现代Web浏览器不允许使用这种弱密码。套件。

私钥盗窃

如果SSL连接使用RSA密钥交换,并且攻击者保留了记录的副本,则此后(可能在几个月之后,可能通过检查废弃的硬盘或磁带上的所有备份来获得私钥的副本,然后他就可以解开握手并解密数据。

Perfect Forward Secrecy是关于应对这种“以后”的问题。您可以使用DHE密码套件来获得它。使用DHE密码套件,可用于解开握手的实际私钥是临时Diffie-Hellman密钥,而不是服务器的RSA(或DSS)私钥。由于是临时性的,它仅存在于RAM中,并且从未写入硬盘。因此,该课程应能更有效地防止小偷。

因此,教训是:通常,如果可能,尝试使用DHE密码套件。您仍应注意备份,不要让私钥泄漏,但是至少DHE套件使泄漏问题减少了一些,特别是如果它在密钥生存期结束后发生(即,对应的证书为No更长的有效期限。)

证书问题

整个证书业务都是SSL的痛点。

从技术上讲,SSL完全独立于X。 509。证书链交换为不透明的斑点。在某些时候,客户端必须使用服务器的公钥,但是客户端可以自由地以其认为合适的任何方式“知道”该密钥。在某些可以使用SSL的特定情况下,客户端已经知道服务器的公共密钥(在代码中进行了硬编码),而只是忽略了服务器发送的证书。不过,在HTTPS的常见情况下,客户端会按照X.509中的说明验证服务器的证书链(以牺牲您的理智为代价进行阅读;已经警告您)。许多攻击媒介,例如:


验证需要验证证书在当前日期仍然有效。客户端计算机如何知道当前日期?使用其内部时钟,并可能通过与NTP服务器通信(以完全不受保护的方式!)。客户端可能会关闭几分钟,几小时,几天甚至几年(我见过),并且在某种程度上,强大的攻击者可能会通过摆弄NTP消息来强迫它。这将使攻击者可以使用几年前被吊销的过时证书。请注意一个有趣的事实:SSL“客户端随机”和“服务器随机”应包含28个随机字节以及本地日期和时间(超过4个字节)。包括时间在内,这是针对基于时间的攻击的变通办法的一部分。我不知道有任何实施能够真正对其进行检查。
直到2003年左右,Internet Explorer / Windows中的证书验证实施均未正确处理“基本约束”扩展。最终结果是,拥有100欧元证书的任何人都可以充当CA,并颁发带有任意选择的名称和密钥的“证书”。
X.509包含一种称为“撤销”的破坏抑制功能:这是有关发布列表的信息。从密码上讲看起来不错的被驱逐的证书,但是不应该被信任(例如,其私钥被盗,或者它们包含错误的名称)。撤消仅在相关各方(即浏览器)接受下载庞大的撤消列表(可能长达数兆字节!)或与OCSP服务器联系时接受。现在的现代浏览器可以这样做,但是有点勉强,如果无法及时获取吊销状态信息(因为人类用户不耐烦),许多浏览器都会接受连接。多年来,总体情况有所改善,但进展缓慢。
某些根CA过去确实犯了一些错误(例如Comodo和DigiNotar)。这导致了伪造证书的颁发(名称是www.microsoft.com,但是私有密钥根本不在Microsoft手中……)。发现了这些错误,并吊销了证书,但仍然提出了一些令人不安的问题(例如,是否有其他CA遇到了此类问题,但没有发现它们,或更糟糕的是,从未注意到它们?)。

X.509是算法,技术,规范和委员会的非常复杂的组合,很难正确地实现。尝试使用像C这样不受保护的编程语言“手动”解码X.509证书是获得缓冲区溢出的一种简便方法。

Bleichenbacher攻击

Daniel Bleichenbacher于1998年发现对RSA的很好的攻击。使用RSA加密数据时(如SSL中的ClientKeyExchange消息所发生的那样),必须填充要加密的数据,以使字节序列的长度与RSA模数相同。填充大部分由随机字节组成,但是有一点结构(值得注意的是,填充后的前两个字节必须为0x00 0x02)。

解密后(在服务器上),填充必须找到并删除。碰巧的是,当时服务器解密但获得了无效的填充(不存在0x00 0x02字节),然后它用警告消息(根据SSL规范)报告了该错误,而有效的填充导致服务器使用看似已解密的值并保持握手状态。

这种事情被称为填充预言。它使攻击者可以发送任意字节序列,就好像它是加密的主控机密一样,并知道解密该序列是否会产生有效的填充。那只是一个1位信息,但是足以恢复具有数百万个请求的私钥(使用精心制作的“加密”字符串)。

解决方法:当解密导致无效时填充时,服务器会继续使用随机的主密码。然后,握手将失败,并显示Finished消息。当前所有的SSL实现都可以做到这一点。

填充Oracle反击

在记录本身中发现填充oracle的另一个区域。考虑CBC加密和HMAC。首先加密要加密的数据,然后再加密结果。使用CBC加密时,要加密的数据的长度必须是块大小的倍数(3DES为8字节,AES为16字节)。因此,应用了具有某种结构的填充。

当时(该攻击是Vaudenay在2002年发现的),当SSL实现正在处理接收到的记录时,它针对这些记录返回了不同的警报消息。两个条件:


解密时,没有找到有效的填充结构。
解密时,找到了有效的填充,但随后对MAC进行了验证并且不匹配。

这是一个填充Oracle,可用于恢复某些加密数据。它需要一个积极的攻击者,但并不难。 Vaudenay实现了它,并扩展到了两种情况下,经过修改的SSL实现返回相同的警报消息的情况,但是在第二种情况下,返回花费的时间更长,因为重新计算MAC花费了时间(定时攻击)。

由于人们从未学习过,因此Rizzo和Duong重新实现了Vaudenay攻击并建立了可恢复HTTP cookie的演示,直到2010年(八年后!),微软在ASP.NET中使用的SSL实施仍未得到修补。

请参阅此页面以获取一些提示。必须注意的是,如果SSL已使用crypto-then-MAC,则可以避免此类问题(错误记录将在MAC级别被拒绝,甚至不考虑解密)。

BEAST

BEAST攻击再次来自Duong和Rizzo,并且再次重现了较早的攻击(来自Philip Rogaway,于2002年)。要了解这个想法,请考虑CBC。在这种操作模式下,每个数据块首先与前一个块的加密结果进行异或;这就是加密XOR的结果。这样做是为了“随机化”块并避免ECB模式下发现的泄漏。由于第一个块没有“上一个”块,因此必须有一个初始化向量(IV),它起着第一个块的前一个块的作用。

事实证明,如果攻击者可以控制要加密的部分数据,还可以预测将要使用的IV,然后他可以将加密机转变为另一个解密预言机,并使用它来恢复其他一些加密数据(攻击者可以不选择)。但是,在SSLv3和TLS 1.0中,攻击者可以预测一条记录的IV:它是前一条记录的最后一块!因此,攻击者必须能够在流中发送一些数据,以“推送”目标数据,在实现构建并发送前一条记录的位置(通常在已累积了16 kB的数据时),但是没有开始构建下一个。

TLS 1.1+受到保护,因为在TLS 1.1(及后续版本)中,使用了按记录的随机IV。对于SSLv3和TLS 1.0,一种解决方法是发送零长度记录:即,记录的有效载荷长度为零-但具有MAC,填充和加密,并且MAC是根据密钥和整个序列计算得出的数字,因此它起着随机数生成器的作用。不幸的是,IE 6.0在零长度记录上令人窒息。其他策略涉及1 / n-1拆分(将一个字节记录作为两个记录发送,一个记录包含一个有效负载的字节,另一个记录保留剩余的n-1)。

另一种解决方法是在可能的情况下强制使用非CBC密码套件-如果客户端发送的密码套件列表中有一个,则服务器会选择基于RC4的密码套件,即使客户端希望使用基于CBC的密码套件也是如此套房。该工具可以告诉您给定的服务器是否显然具有这种功能。 (注意:BEAST是对客户端的攻击,但是,通过选择RC4密码套件,服务器可以保护粗心的客户端。)

有关某些指针,请参见此页。尽管TLS 1.1是2006年发行的,但BEAST攻击可能会迫使浏览器供应商最终升级。的续集。 CRIME利用了几年前理论上的泄漏,但仅在他们最近发布的演示中生动地证明了这一点。 CRIME在与BEAST攻击相同的设置中利用压缩(攻击者可以在SSL连接中发送其自身的一些数据,其中还发送了诸如cookie之类的有趣目标数据)。粗略地说,攻击者会将目标字符串的潜在值放入其数据中,如果匹配,压缩将使结果记录更短。请参阅此问题以进行(认知前的)分析。

完全不使用TLS级别的压缩可以避免CRIME,这是浏览器现在要做的。 Internet Explorer和IIS从来没有首先实现TLS级别的压缩(一次,草率节省了一天); Firefox和Chrome实施了该功能,并于今年夏天停用了它们(Duong和Rizzo事先警告了他们,他们在活动中负有相当的责任)。

CRIME在SSL解释开始之初就说明了我为什么写作:< SSL在很大程度上(但不是绝对)实现了这些目标。



实际上,加密泄漏了加密数据的长度。没有已知的好的解决方案。而长度本身可以揭示很多东西。例如,当使用网络监视器观察SSL连接时,我们可以发现流中的“额外握手”(因为每个记录的第一个字节标识了记录中的数据类型,并且未加密);根据记录的长度,很容易看到客户是否提供了证书。

(编辑:本节于2014年添加- 10-15)

“贵宾犬”攻击利用了基于CBC的密码套件的SSL 3.0特有的漏洞。它依赖于SSL 3.0经常被忽略的功能:大多数填充字节都将被忽略。在TLS 1.0中,完全指定了填充(在记录中添加的字节,以使长度与仅处理完整块的CBC加密兼容);所有字节必须具有特定值,并且接收者会检查该值。在SSL 3.0中,填充字节的内容将被忽略,这使攻击者可以执行大多数未被注意到的更改。更改仅影响不适用的数据,但可以用类似于BEAST的方式用作解密预言。未来

人类从不学习。出于种种原因,在SSL上添加漂亮的扩展存在很大的压力,这些原因一开始看起来总是不错,但可能会引起其他问题。

请考虑一下SSL FalseStart。主要是关于客户端在发送Finished消息后(完全握手)立即发送其应用程序数据,而不必等待服务器发出的Finished消息。这减少了等待时间,这是很好的,而且是精心设计的。但是,它改变了安全状况:在从服务器接收到Finished消息之前,后者仅被隐式认证(客户端尚无证据证明目标服务器确实参与其中;它只知道发送的内容将是仅可由目标服务器读取)。这可能会产生影响;例如,攻击者可能会模拟服务器直到此时,并迫使客户端使用基于CBC的密码套件或TLS压缩。因此,如果客户端实施FalseStart,则会降低针对BEAST和CRIME的保护措施的有效性,否则服务器可能会实施该保护措施。无论如何,“减少30%的等待时间”看起来很奇怪,因为FalseStart仅会对完整的握手产生影响,而对简短的握手则没有影响,因此我不相信这些所谓的好处;至少不会如此。 )

评论


您通过该网站提供良好信息所付出的努力真是疯狂,令人钦佩。非常感激。

–temporary_user_name
16年4月30日在23:07

另请参阅tools.ietf.org/html/rfc7457

–自动机
19年4月5日在8:29