精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。需要全文内容也请联系孙老师。
HTTP是明文协议,比较容易理解,但是HTTPS是密文的,步骤也比较多。TLS是HTTPS相关的安全协议,它依赖证书处理,用到的加密解密方式也有很多种,有的环境下处理机制相对简单,正常环境下处理机制比较复杂。本文是我在解决问题时搜索英语网站得到的,翻译下,让大家有所理解。
I'm trying to debug a TLS handshake between a client and a server我正在尝试调试客户端和服务器之间的TLS握手
Client sends Hello Server sends Hello, Certificate, Certificate request, Server hello done. client sends Encrypted alert - content tpe Alert(21) client sends Client key exchange client sends Change cipher spec server sends Change cipher spec client sends Finished server sends Finished client sends Application data
After this the connection is broken and in the server logs it looks like the client did not send a certificate (where the Encrypted alert happens).
Unfotunetly I cannot paste the wireshark data as I am working in a closed network.
Any help would be greatly appriciated!在此之后连接断开,并且在服务器日志中,它看起来像客户端没有发送证书(加密警报发生的地方)。
Unfotunetly我无法粘贴wireshark数据,因为我在一个封闭的网络中工作。
任何帮助都会非常受欢迎!
In TLS there cannot be an encrypted record before the first handshake is completed; the first encrypted record sent by either the client or the server is a Finished message. If the message is encrypted, then it is meant to be decrypted on the other side; since the symmetric encryption keys are derived from the "master secret" which itself comes from the agreed-upon key exchange mechanism, the receiving end (here, the server) cannot logically decrypt a record before the completion of the key exchange. Thus, from the client, it would make no sense to send an encrypted alert before the ClientKeyExchange (that is, not only doing encryption before the Finishedmessages would violate the standard, but doing so before the ClientKeyExchange would also break the Laws of Nature).在TLS中,在第一次握手完成之前不能有加密记录; 客户端或服务器发送的第一个加密记录是一条Finished消息。如果消息是加密的,那么它意味着在另一方面被解密; 由于对称加密密钥是从“主秘文”导出的,它本身来自商定的密钥交换机制,所以接收端(这里是服务器)在密钥交换完成之前不能逻辑地解密记录。因此,从客户端来看,在此之前发送加密警报ClientKeyExchange是没有意义的(也就是说,不仅在Finished消息违反标准之前进行加密,而且在ClientKeyExchange破坏自然法则之前这样做)。
This leads to two theories:
Perhaps the "encrypted" alert message is not encrypted. An alert record consists in a sequence of "alerts", each of them consisting in a couple of bytes: first byte specifies the alert level (1 = warning, 2 = fatal), second byte documents the nature of the alert. See the standard for details.
Maybe your network trace conflates the traffic from several TLS connections, and the "encrypted alert" pertains to another, older handshake (it could be the close_notify alert that marks the end of the previous connection).
这导致两种理论:
也许“加密”警报消息未加密。警报记录包含一系列“警报”,每个警报包含几个字节:第一个字节指定警报级别(1 =警告,2 =致命),第二个字节记录警报的性质。有关详细信息,请参阅标准
也许您的网络跟踪会混淆来自多个 TLS连接的流量,而“加密的警报”则与另一个较旧的握手有关(它可能是close_notify标记前一个连接结束的警报)。
In any case, if the server requests a client certificate (with a CertificateRequest message), and the client has no suitable certificate, then the client behaviour should be to send an empty Certificatemessage (before its ClientKeyExchange). This is what is supposed to happen with TLS-1.0 and later versions; in SSL-3.0, a client with no suitable certificate would omit the Certificate message altogether, and instead send an alert message of level "warning" and type "no_certificate" (numerical value: 41). If your trace shows no Certificate message from the client, then this would mean that you are using SSL-3.0, which, as of August 2015, is weird (clients and servers should know TLS-1.0 by now). This should be verified by looking at the contents of the ClientHello and ServerHellomessages. An SSL-3.0 handshake would explain the "alert" message, but it would certainly not be encrypted.
(SSL-3.0 and TLS-1.0 are very similar, but have a few differences, one of them being the client behaviour when having been requested a certificate but being unable to provide one.)
在任何情况下,如果服务器请求客户端证书(带有CertificateRequest消息),并且客户端没有合适的证书,则客户端行为应该是发送空Certificate消息(在其之前ClientKeyExchange)。这是TLS-1.0及更高版本应该发生的事情; 在SSL-3.0中,没有合适证书的客户端将Certificate完全省略该消息,而是发送级别为“warning”的警告消息并键入“no_certificate”(数值:41)。如果您的跟踪显示没有Certificate来自客户端的消息,那么这意味着您使用的是SSL-3.0,截至2015年8月,它很奇怪(客户端和服务器现在应该知道TLS-1.0)。这应该通过查看的内容进行验证ClientHello,并ServerHello消息。SSL-3.0握手可以解释“警报”消息,但肯定不会加密。
(SSL-3.0和TLS-1.0非常相似,但有一些差异,其中一个是请求证书但无法提供证书时的客户端行为。)
If you are really using SSL-3.0, then, first, you should not, because SSL-3.0 has an irremediable weakness (called POODLE). However, even if you update to a better versions (one of the TLS versions), you would probably have the same problem, which is that the client does not send a certificate.
Common causes for that are:
The client does not have, indeed, such a certificate. Maybe the certificate is there but has expired (or the client may believe it so, because of a poorly set internal clock). Maybe the client has the certificate but lacks the secret key (e.g. in a Windows world, access rights on the private key are off).
The client has a certificate but it is not appropriate for the server. The CertificateRequest from the server includes the list of names of root CA that the server will use to validate the client certificate. The client will send its certificate only if that certificates can be validated relatively to one of these CA. If the list of root CA is misconfigured on the server, then the client may simply abstain from sending a certificate.
Similarly, the client may believe that its certificate is not appropriate for the server. This is a rare case but it happens in some scenarios involving migrations to a new root CA: given a PKI with a root CA and an intermediate CA, one may create a new root CA (new name, new key) that issues a new certificate for the intermediate CA (but the intermediate CA keeps its name and key). This kind of migration allows existing certificates to be validated against both the old and the new root, which is a good thing for a smooth transition. However, some client software (yeah, Windows, I am looking at you) operates under the belief that a given certificates relates to a single root CA, always. Thus, in such a scenario, if the server wants to use the new root but the client believes its certificate to come from the old root, the client will not send it, even though it would have worked fine on the server side.
如果你真的使用SSL-3.0,那么,首先,你不应该,因为SSL-3.0有一个无法弥补的弱点(称为POODLE)。但是,即使您更新到更好的版本(TLS版本之一),您可能会遇到同样的问题,即客户端不发送证书。
常见原因是:
客户确实没有这样的证书。也许证书在那里但已经过期(或者客户可能会相信它,因为内部时钟设置不当)。也许客户端具有证书但缺少密钥(例如,在Windows世界中,私钥的访问权限已关闭)。
客户端有证书但不适合服务器。在CertificateRequest从服务器包括根CA的名称,该服务器将用于验证客户端证书的列表。仅当证书可以相对于其中一个CA进行验证时,客户端才会发送其证书。如果根CA的列表在服务器上配置错误,则客户端可能只是放弃发送证书。
同样,客户可能会相信它的证书不适合服务器。这是一种罕见的情况,但在涉及迁移到新根CA的某些情况下会发生:给定具有根CA和中间CA的PKI,可以创建发布新证书的新根CA(新名称,新密钥)对于中间CA(但中间CA保留其名称和密钥)。这种迁移允许针对旧根和新根验证现有证书,这对于平滑过渡是一件好事。但是,一些客户端软件(是的,Windows,我正在看着你)运行时认为给定的证书始终与单个根CA相关。因此,在这种情况下,如果服务器想要使用新的根,但客户端认为其证书来自旧的根,则客户端将不会 发送它,即使它在服务器端工作正常。