wireshark tls_使用Wireshark进行调试:TLS

wireshark tls

Sometimes in my darker moments I forget that not all programmers get to work with computer networks every day, like I do. This means that many of you don’t have a chance to experience some of the tools and debugging experiences that I do on a nearly daily basis. This is a real shame, because some of the tools available to programmers working with computer networks are some of the coolest available to any programmer.

有时候,在我更黑暗的时刻,我忘记了并非像我一样,并不是所有的程序员每天都可以使用计算机网络。 这意味着你们中的许多人没有机会体验我几乎每天都会做的一些工具和调试经验。 这实在令人遗憾,因为使用计算机网络的程序员可以使用的某些工具是任何程序员都可以使用的最酷的工具。

Today I’m going to dive into my go-to debugging tool for network problems: Wireshark. This may be the first in a series of posts where I demonstrate how I use Wireshark to investigate networks and to track down bugs in misbehaving implementations.

今天,我将深入研究针对网络问题的调试工具: Wireshark 。 这可能是系列文章中的第一篇,我将演示如何使用Wireshark调查网络并跟踪行为异常的错误。

Today, I’m going to talk about TLS, and Wireshark’s awesome functionality for trying to understand what happens when TLS goes wrong.

今天,我将讨论TLS,以及Wireshark强大的功能,可以尝试了解TLS出错时会发生什么。

无用的错误 (Unhelpful Errors)

Lots of us use tools that work with TLS on a regular basis, usually in the form of HTTPS URLs. If those tools work with OpenSSL, and you’ve ever seen them fail, you’ve likely seen one of OpenSSL’s cryptic error strings pop up in your face. These range from wildly overgeneral (“bad handshake”? What is bad about it?) to the accurate but unhelpful (“EOF in violation of protocol”, no duh). But OpenSSL rarely tells you what the actual problem was, usually because TLS has no good mechanism for communicating problems to the remote peer before terminating the handshake.

我们中的许多人会定期使用与TLS配合使用的工具,通常以HTTPS URL的形式。 如果这些工具可以与OpenSSL一起使用,并且您曾经见过它们失败了,那么您很可能已经看到了OpenSSL的一个隐式错误字符串之一。 这些范围很广,从泛滥(“糟糕的握手”?这有什么不好?)到准确但无济于事(“违反协议的EOF”,没有)。 但是OpenSSL很少告诉您实际的问题是什么,通常是因为TLS在终止握手之前没有将问题传达给远程对等方的良好机制。

For this reason, it becomes extremely helpful to see into a TLS handshake and understand what’s going on. It can help you spot problems and come up with ways to work around them. After a while you can get good enough at this that you can use Wireshark to discover bugs in servers that you don’t operate and cannot reach, and so are effectively a black box, purely by examining TLS handshakes (trust me, there are loads of servers that don’t correctly perform TLS handshakes).

因此,查看TLS握手并了解发生了什么非常有用。 它可以帮助您发现问题并提出解决问题的方法。 一段时间后,您将可以很好地做到这一点,从而可以使用Wireshark来发现无法运行且无法到达的服务器中的错误,因此实际上是黑匣子,仅通过检查TLS握手即可(相信我,这里有很多负载不能正确执行TLS握手的服务器)。

In this case, we’re going to look at a healthy TLS connection, and drill down to how it works. As we investigate the TLS protocol, we’ll also take a look at some places problems arise.

在这种情况下,我们将查看一个健康的TLS连接,并深入研究其工作方式。 在研究TLS协议时,我们还将研究出现问题的地方。

Let’s dive in!

让我们潜入吧!

入门 (Getting Started)

I’m going to use the Chrome web browser to investigate this. All the screenshots here are from Wireshark 2.0.1 on OS X El Capitan 10.11.3 Beta. I highly recommend using a Wireshark that’s at least version 2.0.0: the UI changed drastically for version 2 and is much cleaner and easier to work with.

我将使用Chrome网络浏览器对此进行调查。 这里的所有屏幕截图均来自OS X El Capitan 10.11.3 Beta上的Wireshark 2.0.1。 我强烈建议您使用版本至少为2.0.0的Wireshark:版本2的UI发生了巨大变化,并且更加简洁,易于使用。

We start by opening up Wireshark. This confronts us with a slightly intimidating white screen, but the things we’re most interested in are in the “Capture” section. Here we have two separate options: we can enter a capture filter, and we can select an interface to capture on.

我们首先打开Wireshark。 这给我们带来了一个令人生畏的白色屏幕,但是我们最感兴趣的是“捕获”部分。 在这里,我们有两个单独的选项:我们可以输入捕获过滤器,并且可以选择要捕获的接口。

Let’s talk briefly about capture filters. When you do a packet capture, most of the time you’ll be capturing on your computer’s primary network card. This is likely to include a lot of extraneous data from all of the stuff that’s going on in your computer. For this reason, when you’re debugging you’ll likely want to filter the traffic down to just the things you want.

让我们简短地谈谈捕获过滤器。 进行数据包捕获时,大多数情况下,您将在计算机的主网卡上进行捕获。 这可能包括计算机中正在运行的所有内容中的大量无关数据。 因此,在调试时,您可能希望将流量过滤为所需的内容。

Confusingly, Wireshark uses two filter languages. The one it puts in this box is the Berkley Packet Filter language, which is very simple. For debugging HTTPS connections, you can usually get away with using host and port 443. In this case, as I’ll be investigating the connection between mkcert.org and my machine, I’ll use host mkcert.org and port 443.

令人困惑的是,Wireshark使用两种过滤器语言。 它放入此框中的一种语言是Berkley Packet Filter语言 ,它非常简单。 对于调试HTTPS连接,通常可以使用host and port 443逃脱。 在这种情况下,由于我将研究mkcert.org和我的机器之间的连接,因此我将使用host mkcert.org and port 443

We fill that into the capture filter box, then select the interface we want to capture on. This can be tricky on machines with multiple networked interfaces, or when you have VPNs and other connections active, but in this case it’s relatively simple: I want my MacBook Pro’s wireless card, which is correctly identified as Wi-Fi: en0 by Wireshark. Select the interface by double-clicking, and you’ll get Wireshark’s capture interface:

我们将其填充到捕获过滤器框中,然后选择我们要捕获的接口。 在具有多个网络接口的计算机上,或者在您激活了VPN和其他连接的情况下,这可能会很棘手,但是在这种情况下,这相对简单:我想要MacBook Pro的无线网卡,该无线网卡被Wireshark正确标识为Wi-Fi: en0 。 双击选择接口,您将获得Wireshark的捕获接口:

wireshark tls_使用Wireshark进行调试:TLS_第1张图片

This screen looks intimidating, but it’s not that bad. Up at the top-left you have a few buttons for controlling the capture: specifically, for starting, stopping, and restarting it. These are useful: when you’re done capturing packets you should usually stop the capture, to avoid wasting resources by looking at every packet emitted by your machine!

该屏幕看起来令人生畏,但还不错。 在左上角,有几个按钮用于控制捕获:特别是用于启动,停止和重新启动捕获。 这些很有用:捕获完数据包后,通常应停止捕获,以免通过查看计算机发出的每个数据包而浪费资源!

Right underneath that we have another filter box. This, confusingly, uses a different filter syntax to the one on the landing page, documented here. This syntax is more powerful but harder to use, and so I generally try to use it for very fine-grained work, rather than the general “just give me the host I want” filtering we did earlier.

在下面,我们还有另一个过滤器框。 令人困惑的是,它使用的登陆页面使用的过滤器语法与此处记录的过滤器语法不同。 此语法功能更强大,但更难使用,因此我通常尝试将其用于非常细粒度的工作,而不是像我们之前所做的一般“只给我想要的主机”过滤。

进入Capture UI (Digging Into The Capture UI)

Otherwise, there’s nothing on this page, so let’s go ahead and make a web request to the page. You can use whatever web browser you’d like: I’m using Chrome. Make the request, then switch back to Wireshark and stop the capture.

否则,此页面上没有任何内容,因此让我们继续对该页面进行Web请求。 您可以使用任何想要的网络浏览器:我正在使用Chrome。 发出请求,然后切换回Wireshark并停止捕获。

wireshark tls_使用Wireshark进行调试:TLS_第2张图片

Well, there’s all kinds of stuff going on here! If I tried to explain it all this blog post would be many thousands of words long, so I’m not going to explain the whole thing. Instead, I’m going to explain what the screen shows at a high level.

好吧,这里有各种各样的事情! 如果我试图解释这一切,那么这篇博客文章将包含数千个单词,因此,我将不解释全部内容。 相反,我将解释屏幕的高层显示内容。

Each row of the table is a single network packet as recorded by your operating system. In the case of the network transaction we just captured, this means each row is a single Ethernet frame emitted or received by your network card. Ethernet frames themselves aren’t that useful: therefore, Wireshark also shows all the data for each protocol encapsulated within the lower-level one. In this case, there are five protocols involved:

该表的每一行都是操作系统记录的单个网络数据包。 对于我们刚刚捕获的网络事务,这意味着每一行都是您的网卡发出或接收的单个以太网帧。 以太网帧本身并没有那么有用:因此,Wireshark还显示了封装在较低层协议中的每种协议的所有数据。 在这种情况下,涉及五个协议:

  • 802.11, also known as Ethernet, which comes in ‘frames’.
  • The Internet Protocol, IP, encapsulated inside each ethernet frame, which comes in ‘packets’.
  • The Transmission Control Protocol, TCP, encapsulated inside each IP packet, which comes in ‘segments’.
  • Transport Layer Security, TLS, carried over the TCP bytestream, which comes in ‘records’ and ‘messages’.
  • The Hypertext Transfer Protocol, HTTP, carried inside the encrypted TLS connection. This is invisible to Wireshark, because it should have been encrypted by TLS! (This isn’t actually entirely true: in a future post I’ll talk about how to view encrypted HTTP traffic.)
  • 802.11,也称为以太网,以“帧”形式出现。
  • 互联网协议IP封装在每个以太网框架内,并以“数据包”形式出现。
  • 传输控制协议(TCP)封装在每个IP数据包中,该数据包位于“段”中。
  • 传输层安全性(TLS)承载在TCP字节流中,该字节流出现在“记录”和“消息”中。
  • 超文本传输​​协议HTTP承载在加密的TLS连接中。 这对于Wireshark是不可见的,因为它应该已经由TLS加密! (实际上并非完全如此:在以后的文章中,我将讨论如何查看加密的HTTP流量。)

Wireshark knows lots about network protocols, using components called ‘dissectors’. These dissectors, many of which ship with Wireshark, tell Wireshark how to translate from the bits and bytes from the network into a structured representation of the data. This is why Wireshark is useful: you can avoid hand-decoding the data on the network, and let Wireshark do it for you instead!

Wireshark使用称为“ dissectors”的组件对网络协议了解很多。 这些解剖器(其中许多与Wireshark一起提供)告诉Wireshark如何将网络中的位和字节转换为数据的结构化表示形式。 这就是Wireshark有用的原因:您可以避免手动解码网络上的数据,而让Wireshark为您代劳!

To see how Wireshark displays things, let’s start by looking at packet 1, which in my case is a TCP SYN segment:

要查看Wireshark如何显示内容,让我们首先查看数据包1,在我的情况下,该数据包是TCP SYN段:

wireshark tls_使用Wireshark进行调试:TLS_第3张图片

In the bottom pane of Wireshark, selecting a packet brings up a series of expandable fields. Each field represents one step up the logical Wireshark protocol hierarchy. At the bottom is Wireshark’s own notion of “frames”. This is rarely important, but is useful to know when you see it. Next up is the Ethernet frame: Wireshark displays the source and destination MAC addresses on that Ethernet frame in the info block. After that comes the encapsulated IPv4 packet, with Wireshark again showing source and destination IP addresses very clearly. You can expand this to see all the other information Wireshark has about that IP packet. Last, and expanded in my image, is the TCP segment. This shows all the useful information carried on that TCP segment, which in this case is mostly limited to the flags, which shows that the SYN flag is set. This is the first step of TCP’s connection handshake, so looking at this tells us that a TCP connection is being established.

在Wireshark的底部窗格中,选择一个数据包将显示一系列可扩展字段。 每个字段代表逻辑Wireshark协议层次结构的上一步。 底部是Wireshark自己的“框架”概念。 这很少重要,但是在您看到它时很有用。 接下来是以太网帧:Wireshark在信息块中显示该以太网帧上的源和目标MAC地址。 之后是封装的IPv4数据包,Wireshark再次非常清楚地显示了源IP地址和目标IP地址。 您可以展开它以查看Wireshark关于该IP数据包的所有其他信息。 最后,在我的图片中扩展的是TCP段。 这显示了该TCP段上携带的所有有用信息,在这种情况下,该信息主要限于标志,这表明已设置SYN标志。 这是TCP连接握手的第一步,因此查看此信息可以告诉我们正在建立TCP连接。

So, with a basic understanding of how to look at things in Wireshark, let’s dive into the TLS handshake. Firstly, though, we need to simplify the view using one of my Wireshark top tips. Because we connected in Chrome, there are a whole lot of TLS handshakes in here as Chrome made many web requests: in fact, I can see three started at once. Let’s look at just one of them for now. If you pick a packet that’s part of the connection you want to look at, you can right click on it and select “Follow -> TCP Stream”. This will do two things: firstly, it’ll pop up a window containing all the data on that TCP stream, in order, colorized appropriately for each party. This can be very useful when you want to view a HTTP request/response completely, rather than split across multiple TCP segments, but we don’t need it here, so close it. The more important thing it does is set a filter (in this case, “tcp.stream eq 0”) that removes all packets from other TCP connections from the window. This lets us see just the one handshake, without getting distracted by different connections.

因此,在基本了解如何在Wireshark中查看内容后,让我们深入了解TLS握手。 但是,首先,我们需要使用我的Wireshark最重要的技巧之一来简化视图。 由于我们是通过Chrome连接的,因此这里有很多TLS握手,因为Chrome提出了许多Web请求:实际上,我可以看到三个请求同时启动了。 现在让我们只看其中之一。 如果选择了要查看的连接中的数据包,则可以右键单击它,然后选择“关注-> TCP流”。 这将做两件事:首先,它将弹出一个窗口,其中依次包含该TCP流上的所有数据,并为每一方适当地着色。 当您想完全查看HTTP请求/响应,而不是将其拆分为多个TCP段时,这可能非常有用,但是我们在这里不需要它,因此请关闭它。 更重要的是设置了一个过滤器(在本例中为“ tcp.stream eq 0”),该过滤器从窗口中的其他TCP连接中删除了所有数据包。 这使我们只看到一次握手,而不会因其他连接而分心。

TLS握手 (The TLS Handshake)

Let’s start by scrolling down to the first packet Wireshark identifies as having a “TLSv1.2” record in it. Selecting it, you’ll notice that Wireshark has a new level of its expandable selectors: “Secure Sockets Layer”. This is the old name for TLS.

让我们从向下滚动到Wireshark标识为其中包含“ TLSv1.2”记录的第一个数据包开始。 选择它,您会注意到Wireshark具有新级别的可扩展选择器:“安全套接字层”。 这是TLS的旧名称。

Inside it, Wireshark says there’s one TLS handshake message contained here: a “Client Hello” message. This is, coincidentally, the first message sent as part of a TLS connection, and it’s sent by the client. If you expand this message up, you’ll see that it’s very long (197 bytes in my case), and contains lots of information!

Wireshark表示,其中包含一个TLS握手消息:“ Client Hello”消息。 碰巧的是,这是作为TLS连接的一部分发送的第一条消息,它是由客户端发送的。 如果扩大此消息,您会发现它很长(以我的情况为197个字节),并且包含很多信息!

客户您好 ( Client Hello)

Let’s talk about the Client Hello message for a moment. The purpose of this message is to let the client give the server some information about what it wants to do. There’s loads of data here, but I’ll take you into the things that are most important to understand (in part because they’re the bits that go wrong the most).

让我们讨论一下“客户端问候”消息。 该消息的目的是让客户端向服务器提供有关其要执行的操作的信息。 这里有大量数据,但是我将带您进入最重要的要理解的部分(部分原因是它们是最容易出错的部分)。

版本号 (Versions)

Firstly, you can see that there are actually two TLS version fields here: the first is in the outer TLS wrapper, while the second is inside the Client Hello. The outer TLS field is a lower version than the inner one: in this case, the outer layer is TLSv1.0, while the inner layer is TLSv1.2. This acts essentially to bound the set of TLS versions the client and server support: here, the client is saying that the lowest TLS version it’ll use is TLSv1, while the newest is TLSv1.2. Some servers mistakenly only care about the outer version number, and will shut down connections that don’t advertise themselves as sufficiently new1.

首先,您可以看到这里实际上有两个TLS版本字段:第一个在外部TLS包装程序中,而第二个在客户端Hello内部。 外部TLS字段的版本低于内部TLS字段:在这种情况下,外部层是TLSv1.0,而内部层是TLSv1.2。 这实质上是用来绑定客户端和服务器支持的TLS版本集:在这里,客户端表示它将使用的最低TLS版本是TLSv1,而最新版本是TLSv1.2。 一些服务器错误地只在乎外部版本号,并且会关闭那些没有将自身宣传为足够新的连接1

密码套房 (Cipher Suites)

The next thing to note is the cipher suites section. You can open that up, and Wireshark will handily show you the names of every cipher suite offered by the client, and the order in which they were sent. A TLS connection can only be established using a cipher suite supported by both client and server, and in principle the order of the cipher suites sent by the client represents a preference order. In practice, many servers ignore the client’s preferences. Here, Chrome has only sent a very small number of cipher suites. One common error is to have misconfigured OpenSSL so that it does not send the correct cipher suites: you can check here whether it’s doing the right thing.

接下来要注意的是密码套件部分。 您可以打开它,Wireshark会轻松地向您显示客户端提供的每个密码套件的名称以及它们的发送顺序。 只能使用客户端和服务器均支持的密码套件来建立TLS连接,并且原则上客户端发送的密码套件的顺序表示优先顺序。 实际上,许多服务器会忽略客户端的首选项。 在这里,Chrome仅发送了非常少量的密码套件。 一个常见的错误是OpenSSL配置错误,因此它不会发送正确的密码套件:您可以在此处检查它是否做对了。

压缩 (Compression)

Moving further down, we have the “Compression Methods” section. The only thing that should be here is the NULL compression method, because TLS compression is known to be broken.

再往下走,我们有“压缩方法”部分。 此处唯一应该是NULL压缩方法,因为已知TLS压缩已被破坏。

服务器名称指示 (Server Name Indication)

The next thing to see is the “server_name” extension. This extension, whose full name is Server Name Indication (SNI), is used to enable virtual hosting. Virtual hosting is where many websites are co-located on the same server, so they all have the same IP address. For plaintext HTTP the server will normally wait for the Host: header to work out what website to use, but for TLS the server needs to present the appropriate TLS certificate before the client sends any HTTP data. For this reason, the Server Name Indication extension tells the server what hostname the client is trying to contact, so that the server can present the correct TLS certificate.

接下来要看的是“ server_name”扩展名。 此扩展名(全名是服务器名称指示(SNI))用于启用虚拟主机。 虚拟主机是许多网站位于同一服务器上的位置,因此它们都具有相同的IP地址。 对于纯文本HTTP,服务器通常将等待Host:标头确定要使用的网站,但是对于TLS,服务器需要在客户端发送任何HTTP数据之前出示相应的TLS证书。 因此,服务器名称指示扩展名告诉服务器客户端尝试联系的主机名,以便服务器可以提供正确的TLS证书。

Common problems with this field include:

该领域的常见问题包括:

  • not sending it at all
  • sending an IP address in it (not allowed!)
  • 完全不发送
  • 在其中发送IP地址(不允许!)

下一协议协商和应用层协议协商 (Next Protocol Negotiation and Application Layer Protocol Negotiation)

Modern TLS requests may have either or both of the Next Protocol Negotiation or Application Layer Protocol Negotiation extensions in them. The purpose of these extensions is to allow the server and client to agree on what protocol to speak inside the encrypted TLS tunnel. The primary use right now is to decide between HTTP/1.1 and HTTP/2.

现代TLS请求中可能包含“下一协议协商”或“应用程序层协议协商”扩展中的一个或两个。 这些扩展的目的是允许服务器和客户端就在加密的TLS隧道内使用哪种协议达成共识。 现在的主要用途是在HTTP / 1.1和HTTP / 2之间做出决定。

The two extensions are very similar. The key difference is that, in NPN, the final protocol choice is made by the client, whereas in ALPN the final protocol choice is made by the server. For this reason, if you open up the two extensions you’ll see that the client merely sends the NPN extension with no data, but in ALPN it sends the protocols it can speak. In NPN, the client wants to hear what the server can speak before it chooses (which it’ll be told in the Server Hello), while in ALPN the server needs to know what the client can speak.

这两个扩展非常相似。 关键区别在于,在NPN中,最终协议选择由客户端决定,而在ALPN中,最终协议选择由服务器决定。 因此,如果打开这两个扩展,您将看到客户端仅发送不包含数据的NPN扩展,但是在ALPN中,它将发送它可以说的协议。 在NPN中,客户端希望在选择之前先听到服务器会说的话(服务器Hello中会告诉您),而在ALPN中,服务器需要知道客户端会说什么。

其他 (Others)

There are some other useful fields here that are worth checking out (e.g. the Elliptic Curves extension), but I recommend you look at them independently of this post: they’re rarely the source of problems on the handshake.

这里还有一些其他有用的字段值得检查(例如“椭圆曲线”扩展名),但我建议您独立于本文查看它们:它们很少是握手问题的根源。

服务器你好 (Server Hello)

The next message is going back the other way, from the server to the client, and it’s called the Server Hello. This message serves a similar purpose to the Client Hello: it lets the server tell the client important information about how the TLS connection will progress and what the server can do.

下一条消息是从服务器到客户端的另一种返回方式,称为“服务器Hello”。 该消息的用途类似于“客户端问候”:它使服务器可以将TLS连接如何进行以及服务器可以做什么的重要信息告知客户端。

The key difference between the Server Hello and the Client Hello is that, while the Client Hello is informational, the Server Hello is instructional. In the Client Hello the client says “I can do X”, while in the Server Hello the server says “we will do X”.

服务器问候和客户端问候之间的主要区别在于,尽管客户端问候是信息性的,但服务器问候是指导性的。 在客户端Hello中,客户端说“我可以做X”,而在服务器Hello中,服务器说“我们将做X”。

If, in your debugging, the connection never gets as far as a Server Hello, this means that the server was unprepared to accept the connection entirely. The most common cause of this is actually connecting to a port that wanted to do unencrypted HTTP, but other problems are usually around TLS versions and cipher suites: see above for how to check those fields.

如果在调试中,连接从未达到服务器Hello的程度,则表明服务器没有准备好完全接受连接。 最常见的原因实际上是连接到想要执行未加密HTTP的端口,但是其他问题通常与TLS版本和密码套件有关:有关如何检查这些字段的信息,请参见上文。

The following fields of the Server Hello are of interest.

Server Hello的以下字段令人感兴趣。

版本号 (Versions)

Like the Client Hello, there are two version numbers in the Server Hello: one in the outer wrapper and one in the message itself. Unlike the Client Hello, these should be the same. This is because the Server should have chosen a TLS version to use. In almost all cases this will be the highest common version between the client and server. In the case of my example, that’s TLSv1.2.

与客户端Hello一样,Server Hello中有两个版本号:一个在外部包装中,一个在消息本身中。 与客户端Hello不同,它们应该相同。 这是因为服务器应该选择要使用的TLS版本。 在几乎所有情况下,这都是客户端和服务器之间的最高通用版本。 在我的示例中,这是TLSv1.2。

密码套件 (Cipher Suite)

This is the cipher suite that will be used for the rest of the connection. In this case, the server has chosen TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. This is one of the strongest cipher suites available to TLS, and represents a good choice by the server.

这是密码套件,将用于其余的连接。 在这种情况下,服务器选择了TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 。 这是TLS可用的最强大的密码套件之一,代表服务器的不错选择。

Generally, it’s a red flag to see a cipher suite with either MD5 or RC4 in it, and cipher suites with ECDHE and AES GCM are preferred. Note that AES CBC is not AES GCM: be warned!

通常,看到其中包含MD5或RC4的密码套件是一个危险信号,并且首选具有ECDHE和AES GCM的密码套件。 请注意,AES CBC不是AES GCM:警告!

压缩方式 (Compression Method)

As mentioned above, this had better be NULL! Anything else is extremely dangerous.

如上所述,最好将其设置为NULL! 其他任何事情都是极其危险的。

NPN和ALPN (NPN and ALPN)

Here, again, you can see the NPN and ALPN extension fields. They’ll be populated differently, if they’re both present at all. If NPN is used, the server will be sending back a list of protocols it is willing to speak. If ALPN is being used, the server will send back the protocol that will be spoken after the connection.

再次在这里,您可以看到NPN和ALPN扩展字段。 如果它们都存在,它们的填充方式将有所不同。 如果使用NPN,则服务器将发回它愿意发言的协议列表。 如果正在使用ALPN,则服务器将发回连接后将使用的协议。

If ALPN/NPN were offered but the server doesn’t support them, neither extension will be sent back, and the client will fall back to HTTP/1.1.

如果提供了ALPN / NPN,但服务器不支持它们,则不会发送回任何扩展名,并且客户端将回退到HTTP / 1.1。

Here the server doesn’t support ALPN, so sent no response to that. It does support NPN, but only supports HTTP/1.1 traffic.

该服务器不支持ALPN,因此未发送任何响应。 它确实支持NPN,但仅支持HTTP / 1.1通信。

证书 (Certificate)

The next message also comes from the server, and is the Certificate message. Here the server sends a serialized representation of the TLS certificates that the client should validate.

下一条消息也来自服务器,即证书消息。 服务器在此发送客户端应验证的TLS证书的序列化表示。

These certificates perform a vital role. Firstly, they let a client authenticate a server, so that the client can confirm that the server is allowed to send data for the domain name being reached. Secondly, they provide the client with a public key that is used to help establish the encryption with some cipher suites.

这些证书起着至关重要的作用。 首先,它们让客户端对服务器进行身份验证,以便客户端可以确认允许服务器发送要访问的域名的数据。 其次,它们向客户端提供一个公共密钥,该公共密钥用于帮助通过某些密码套件建立加密。

Happily, Wireshark understands the format of these certificates, so you can dig into them and see the certificates in detail. In general the first of these should be the ‘leaf’ certificate, which should correspond to the domain name being requested.

令人高兴的是,Wireshark理解这些证书的格式,因此您可以深入研究它们并详细查看证书。 通常,第一个应该是“叶子”证书,该证书应与所请求的域名相对应。

If your TLS client fails to validate the certificate, there could be a number of problems:

如果您的TLS客户端无法验证证书,则可能存在许多问题:

  1. The leaf certificate may not be valid for the domain. A certificate is valid if either it has the correct “dNSName” (not a typo) field in its Subject Alternative Name (subjectAltName, or SAN) extension, or if it has the correct “commonName” (displayed by Wireshark as “id-at-commonName”) field in its Subject field.
  2. The leaf certificate may not chain up to a trusted root certificate. In general this happens in one of two ways:
    1. The server may not be sending “intermediate certificates”. In general a leaf certificate is signed by a certificate that is not itself a trusted root certificate. A well-configured server will actually provide that intermediate certificate as part of the Certificate message, to prevent clients needing to have every intermediate certificate in the world in their trust database, but this doesn’t always happen.
    2. The server may have a cross-signed trust root. This breaks some older TLS stacks. I won’t go into it here, because it’s too complex and makes me sad.
  1. 叶证书可能对该域无效。 如果证书在其主题备用名称(subjectAltName或SAN)扩展名中具有正确的“ dNSName”(不是错字)字段,或者具有正确的“ commonName”(由Wireshark显示为“ id-at”,则该证书有效) -commonName”)的“主题”字段中。
  2. 叶证书可能不会链接到受信任的根证书。 通常,这以两种方式之一发生:
    1. 服务器可能没有发送“中间证书”。 通常,叶子证书由本身不是受信任的根证书的证书签名。 配置良好的服务器实际上会将该中间证书作为“证书”消息的一部分提供,以防止客户端需要在其信任数据库中拥有世界上的每个中间证书,但这并非总是如此。
    2. 服务器可能具有交叉签名的信任根。 这会破坏一些较旧的TLS堆栈。 我不会在这里讨论它,因为它太复杂了,让我很难过。

服务器密钥交换(可选) (Server Key Exchange (Optional))

Immediately following the Certificate message the server may send a Server Key Exchange message. This is sent only for specific cipher suites: specifically, either DHE or ECDHE cipher suites. This message is used to establish the ephemeral key for the encryption algorithm using Diffie-Hellman (or Elliptic-Curve Diffie-Hellman) key negotiation.

在证书消息之后,服务器可以立即发送服务器密钥交换消息。 仅针对特定的密码套件发送此消息:特别是DHE或ECDHE密码套件。 该消息用于为使用Diffie-Hellman(或Elliptic-Curve Diffie-Hellman)密钥协商的加密算法建立临时密钥。

I’m not going to go into the structure of this message too much because if it’s wrong then your server is so totally screwed there’s no saving you. However, in general this will contain the server’s half of the information required for the Diffie Hellman negotiation.

我不会过多地讨论此消息的结构,因为如果错了,那么您的服务器就完全被搞砸了,那就无济于事。 但是,通常,这将包含Diffie Hellman协商所需的服务器信息的一半。

服务器Hello完成 (Server Hello Done)

The next message should be the Server Hello Done, also sent by the server. This does exactly what it says on the tin: tells the client that the Server Hello is over. This is needed because of some optional messages that I’m not covering here, mostly used with TLS client certificates, that are also part of the Server Hello.

下一条消息应该是服务器发送的服务器已完成。 这完全符合其提示:告诉客户端服务器问候已经结束。 这是必需的,因为我在这里不介绍一些可选消息,这些消息主要与TLS客户端证书一起使用,它们也是Server Hello的一部分。

客户密钥交换 (Client Key Exchange)

This message may be sent if the server sent a Server Key Exchange message. This is used for the client’s portion of the Diffie-Hellman key negotiation. I’m not going to go into this further here.

如果服务器发送了服务器密钥交换消息,则可能会发送此消息。 这用于Diffie-Hellman密钥协商的客户端部分。 我在这里不做进一步介绍。

更改密码规范 (Change Cipher Spec)

This is an interesting one, because it’s not strictly a part of the handshake protocol. Instead, it tells the remote party that all further messages will be encrypted using the agreed-upon cipher suite. This can only be done at this point because it’s guaranteed that the key exchange will be complete, that the certificates will have been verified, and that everyone is happy to continue with the transaction.

这很有趣,因为它严格来说并不是握手协议的一部分。 取而代之的是,它告诉远程方使用约定的密码套件对所有其他消息进行加密。 这只能在此刻完成,因为可以确保密钥交换将完成,证书将被验证,并且每个人都乐于继续进行交易。

The server will send a Change Cipher Spec message as well.

服务器还将发送“更改密码规范”消息。

做完了! (Done!)

At this point, we can no longer see into the rest of the TLS handshake. Happily, the handshake very rarely fails at this point because all that remains is for both sides to send their Finished message, encrypted using the agreed cipher suite.

在这一点上,我们不再能看到其余的TLS握手。 幸运的是,此时握手很少会失败,因为剩下的一切都是双方发送使用已确定的密码套件加密的Finished消息的。

旁注:加密警报 (Side Note: Encrypted Alert)

Depending on how screwed up your client and server are, it is possible that an error will occur during the key exchange. This won’t get discovered until after the Change Cipher Spec, which means you won’t see a very clear error. However, Wireshark will note that your client/server received an “Encrypted Alert”. This is very often the result of broken key negotiation, and should be investigated.

根据客户端和服务器的损坏程度,密钥交换期间可能会发生错误。 直到更改密码规范之后,才可以发现此错误,这意味着您不会看到非常明显的错误。 但是,Wireshark将注意到您的客户端/服务器收到了“加密警报”。 这通常是密钥协商破裂的结果,应进行调查。

往下 (Up Next)

This represents a very high-level overview of the way the TLS handshake is done. As you can see, it’s already pretty complicated and lengthy, and that is without going into any of the cryptographic signing and negotiation that is happening along the way.

这是TLS握手完成方式的高级概述。 如您所见,它已经相当复杂且冗长,而且无需进行任何加密签名和协商。

I highly recommend taking 15 or 20 more minutes to look at the handshake in more detail, and to Google anything you don’t understand. You should also consider capturing handshakes from other websites, to see how they differ from the one you’ve looked at here.

我强烈建议您多花15或20分钟的时间来详细了解握手过程,并向Google提出您不了解的任何问题。 您还应该考虑从其他网站捕获握手,以了解它们与您在此处看到的握手有何不同。

  1. Actually, there’s some complexity around this field. In the upcoming TLSv1.3 standard, the spec will require that the outer version number always be set to TLSv1.0. This is done with a goal of minimizing the number of mistakes servers and clients can make by paying attention to or incorrectly setting the outer version number. Regardless, this remains a field worth keeping an eye on. ↩

  1. 实际上,该领域存在一些复杂性。 在即将到来的TLSv1.3标准中,规范将要求外部版本号始终设置为TLSv1.0。 这样做的目的是通过注意或错误设置外部版本号来最大程度减少服务器和客户端可能犯的错误。 无论如何,这仍然是一个值得关注的领域。 ↩

翻译自: https://www.pybloggers.com/2016/01/debugging-with-wireshark-tls/

wireshark tls

你可能感兴趣的:(网络,过滤器,python,java,http)