tls证书验证
A walk-through of a simplified implementation of mTLS.
mTLS简化实现的演练。
First, what is TLS?
首先,什么是TLS?
Transport Layer Security (TLS), and its now-deprecated predecessor, Secure Sockets Layer (SSL),[1] are cryptographic protocols designed to provide communications security over a computer network.[2] Several versions of the protocols find widespread use in applications such as web browsing, email, instant messaging, and voice over IP (VoIP). Websites can use TLS to secure all communications between their servers and web browsers.
传输层安全性(TLS)及其现在不推荐使用的安全套接字层(SSL)[1]是旨在在计算机网络上提供通信安全性的加密协议。[2] 协议的几种版本在Web浏览,电子邮件,即时消息传递和IP语音(VoIP)等应用程序中得到广泛使用。 网站可以使用TLS来保护其服务器与Web浏览器之间的所有通信。
— Wikipedia — Transport Layer Security
—维基百科— 传输层安全
Yes, it is the mechanism by which our web browsers create secure connections to web servers. Just click on the lock in your browser’s address bar when visiting most any web site and you will get an informational popup.
是的,这是我们的Web浏览器创建与Web服务器的安全连接的机制。 在访问大多数网站时,只需单击浏览器地址栏中的锁,您将看到一个信息弹出窗口。

At the heart of TLS is Public Key Infrastructure (PKI) and in particular X.509 certificates.
TLS的核心是公钥基础结构(PKI),尤其是X.509证书。
In cryptography, X.509 is a standard defining the format of public key certificates.[1] X.509 certificates are used in many Internet protocols, including TLS/SSL, which is the basis for HTTPS[2], the secure protocol for browsing the web. They are also used in offline applications, like electronic signatures. An X.509 certificate contains a public key and an identity (a hostname, or an organization, or an individual), and is either signed by a certificate authority or self-signed. When a certificate is signed by a trusted certificate authority, or validated by other means, someone holding that certificate can rely on the public key it contains to establish secure communications with another party, or validate documents digitally signed by the corresponding private key.
在密码术中,X.509是定义公共密钥证书格式的标准。[1] X.509证书用于许多Internet协议中,包括TLS / SSL,这是HTTPS [2](浏览网页的安全协议)的基础。 它们还用于脱机应用程序,例如电子签名。 X.509证书包含公钥和身份(主机名,组织或个人),并且由证书颁发机构签名或自行签名。 当证书由受信任的证书颁发机构签名或通过其他方式进行验证时,持有该证书的人可以依靠其包含的公钥与另一方建立安全通信,或验证由相应私钥进行数字签名的文档。
— Wikipedia — X.509
—维基百科— X.509
To inspect a X.509 certificate, click on the Certificate entry in the informational popup (shown when we clicked on the lock above).
要检查X.509证书,请在信息弹出窗口中单击“ 证书”条目(当我们单击上面的锁时显示)。
So then, what is mTLS?
那么,什么是mTLS?
By default the TLS protocol only proves the identity of the server to the client using X.509 certificate and the authentication of the client to the server is left to the application layer. TLS also offers client-to-server authentication using client-side X.509 authentication.[1] As it requires provisioning of the certificates to the clients and involves less user-friendly experience, it’s rarely used in end-user applications.
默认情况下,TLS协议仅使用X.509证书向客户端证明服务器的身份,而客户端对服务器的身份验证则留给应用程序层。 TLS还使用客户端X.509身份验证提供客户端到服务器的身份验证。[1] 由于它需要向客户端提供证书,并且涉及的用户友好性较差,因此很少在最终用户应用程序中使用。
Mutual TLS authentication (mTLS) is much more widespread in business-to-business (B2B) applications, where a limited number of programmatic and homogeneous clients are connecting to specific web services, the operational burden is limited, and security requirements are usually much higher as compared to consumer environments.
相互TLS身份验证(mTLS)在企业对企业(B2B)应用程序中更为广泛,其中有限数量的编程和同类客户端正在连接到特定的Web服务,操作负担有限,并且对安全性的要求通常更高与消费者环境相比。
— Wikipedia — Mutual authentication
—维基百科— 相互认证
With all this in mind, let us walk through a mTLS example of using the cURL web browser (the client) to connect to a Node.js web server (the server) serving on the DNS name localhost. In doing so:
考虑到所有这些,让我们来看一个使用cURL Web浏览器(客户端)连接到DNS名称为localhost的Node.js Web服务器(服务器)的mTLS示例。 在这样做:
The client will validate that the server is trusted to serve up content for the DNS name localhost
客户端将验证服务器是否可以提供DNS名称localhost的内容
- The server will validate the client is known, i.e., it will authenticate it 服务器将验证客户端是已知的,即它将对其进行身份验证
The first step is to create a certificate authority (CA) that both the client and server trust. The CA is just a public and private key with the public key wrapped up in a self-signed X.509 certificate. The command we use to do this is:
第一步是创建一个客户端和服务器都信任的证书颁发机构(CA)。 CA只是一个公钥和私钥,公钥包含在自签名的X.509证书中。 我们用于执行此操作的命令是:
openssl req \
-new \
-x509 \
-nodes \
-days 365 \
-subj '/CN=my-ca' \
-keyout ca.key \
-out ca.crt
This outputs two files, ca.key and ca.crt, in the PEM format (base64 encoding of the private key and X.509 certificate respectively).
这将以PEM格式 (分别为私钥和X.509证书的base64编码)输出两个文件ca.key和ca.crt 。
Looking at the openssl req documentation, we see that the -new and -x509 options enable the creation of a self-signed root CA X.509 certificate. The nodes (No DES) option disables securing the private key with a pass-code; this option is optional. The subj option provides the CA’s identity; in this case the Common Name (CN) of my-ca. The remaining options are self-explanatory.
查看openssl req 文档 ,我们看到-new和-x509选项启用了自签名根CA X.509证书的创建。 节点 (无DES)选项禁止使用密码保护私钥; 此选项是可选的。 subj选项提供CA的身份; 在这种情况下, my-ca的通用名称(CN)。 其余选项不言自明。
We can turn-around and inspect the certificate using the following command:
我们可以使用以下命令来周转和检查证书:
openssl x509 \
--in ca.crt \
-text \
--noout
The options here are self-explanatory as documented in the openssl x509 documentation.
如openssl x509 文档中所述,此处的选项不言自明。
Looking at the output, we can confirm a number of things:
查看输出,我们可以确认以下几点:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
[OBMITTED]
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = my-ca
Validity
Not Before: Jun 13 00:49:48 2020 GMT
Not After : Jun 13 00:49:48 2021 GMT
Subject: CN = my-ca
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
[OBMITTED]
Exponent: [OBMITTED]
X509v3 extensions:
X509v3 Subject Key Identifier:
[OBMITTED]
X509v3 Authority Key Identifier:
keyid:[OBMITTED] X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
[OBMITTED]
Both the Subject and Issuer have the value CN = my-ca; this indicates that this certificate is self-signed
主题和颁发者的值均为CN = my-ca; 这表明该证书是自签名的
The Validity indicates that the certificate is valid for a year
有效期表明证书有效期为一年
The X509v3 Basic Constraints value CA:TRUE indicate that this certificate can be used as a CA, i.e., can be used to sign certificates
X509v3基本约束值CA:TRUE表示此证书可以用作CA,即可以用来签署证书
Next we create the server’s key and certificate; starting with the key:
接下来,我们创建服务器的密钥和证书; 从键开始:
openssl genrsa \
-out server.key 2048
The options here are self-explanatory as documented in the openssl genrsa documentation.
此处的选项是不言自明的,如openssl genrsa 文档中所述 。
Remember, our goal here is to create a server certificate for the DNS name localhost signed by the CA. We now create a Certificate Signing Request (CSR) with the Common Name (CN) localhost:
记住,我们的目标是为由CA签名的DNS名称localhost创建服务器证书。 现在,我们用通用名称(CN) localhost创建一个证书签名请求(CSR):
openssl req \
-new \
-key server.key \
-out server.csr
Using the CSR, the CA (really using the CA key and certificate) creates the signed certificate:
使用CSR,CA(实际上使用CA密钥和证书)创建签名证书:
openssl x509 \
-req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 365 \
-out server.crt
The output is the signed server certificate, server.crt, in the PEM format.
输出为PEM格式的签名服务器证书server.crt 。
Most of the options are either familiar (from above) or self-explanatory as documented in the openssl x509 documentation. The one exception is the CAcreateserial option that manages a newly created file, ca.srl, that enables each certificate created by this CA to have a unique serial number.
多数选项是熟悉的(从上方)或不加解释,如openssl x509 文档中所述 。 一个例外是CAcreateserial选项,该选项管理一个新创建的文件ca.srl ,该文件使该CA创建的每个证书都具有唯一的序列号。
As before we inspect the certificate using the following command:
和以前一样,我们使用以下命令检查证书:
openssl x509 \
--in server.crt \
-text \
--noout
Looking at the output, we can confirm a number of things:
查看输出,我们可以确认以下几点:
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
[OBMITTED]
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = my-ca
Validity
Not Before: Jun 13 00:50:18 2020 GMT
Not After : Jun 13 00:50:18 2021 GMT
Subject: CN = localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
[OBMITTED]
Exponent: [OBMITTED]
Signature Algorithm: sha256WithRSAEncryption
[OBMITTED]
The Issuer has the value CN = my-ca; this indicates that this certificate is signed by the my-ca certificate authority
发行者的值为CN = my-ca; 这表明此证书是由my-ca证书颁发机构签名的
The Validity indicates that the certificate is valid for a year
有效期表明证书有效期为一年
The Subject has the value CN = localhost; this indicates that this certificate can be served to a client to validate that the server is trusted to serve up content for the DNS name localhost
主题的值为CN = localhost ; 这表明可以将该证书提供给客户端,以验证服务器是否可以信任DNS名称localhost的内容。
We essentially repeat the process to create the client’s key and certificate; starting by creating the client’s key:
我们实质上重复创建客户密钥和证书的过程; 首先创建客户的密钥:
openssl genrsa \
-out client.key 2048
Creating the CSR with the arbitrary Common Name of my-client:
使用my-client的任意通用名称创建CSR :
openssl req \
-new \
-key client.key \
-out client.csr
And finally the creating the client’s certificate:
最后是创建客户的证书:
openssl x509 \
-req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-days 365
note: If you inspect this certificate, you will observe that the Serial Number is indeed different than the server’s certificate.
注意 :如果您检查此证书,则会发现序列号确实与服务器的证书不同。
One observation is that both the server and client certificates are simpler X.509 v1 certificates; the CA certificate however is a X.509 v3 certificate. This is because OpenSSL automatically creates X.508 v3 self-signed certificates (CA certificate) and we did not supply any v3 extensions when signing the server and client certificates (using the extfile and extensions options).
一种观察结果是,服务器证书和客户端证书都是较简单的X.509 v1证书。 但是,CA证书是X.509 v3证书。 这是因为OpenSSL自动创建X.508 v3自签名证书(CA证书),并且在对服务器证书和客户端证书进行签名时(使用extfile和extensions选项)我们没有提供任何v3扩展名 。
note: The use of various X.509 v3 extensions is outside the scope of this article; besides I have not found any simple explanations of them myself.
注意 :各种X.509 v3扩展的使用超出了本文的范围; 除了我自己,我还没有找到任何简单的解释。
With all of our keys and certificates (ca, server, and client) created we can configure our server and client.
使用我们创建的所有密钥和证书(ca,服务器和客户端),我们可以配置服务器和客户端。
The server is the basic Hello World example, provided by Node.js, enhanced to support mTLS.
该服务器是Node.js提供的基本Hello World示例 ,已增强为支持mTLS。
Here the requestCert, rejectUnauthorized, and ca options are used to require the browser (client) to supply a certificate signed by the CA certificate to interact with the server.
在这里, requestCert , rejectUnauthorized和ca选项用于要求浏览器(客户端)提供由CA证书签名的证书,以便与服务器进行交互。
The key and cert options enable the server to serve up the CA signed server certificate.
密钥和证书选项使服务器可以提供CA签名的服务器证书。
The client is simply the cURL web browser with options:
客户端只是具有以下选项的cURL Web浏览器:
curl \
--cacert ca.crt \
--key client.key \
--cert client.crt \
https://localhost:3000
Here the cacert option is used so that the client (cURL) can validate the server supplied certificate. The key and cert are used so the client sends the CA signed client certificate with the request.
在这里,使用cacert选项,以便客户端(cURL)可以验证服务器提供的证书。 使用密钥和证书 ,以便客户端将CA签名的客户端证书与请求一起发送。
Indeed, we observe that this request successfully returns hello world. If, however, we leave off the cacert option, we get the error:
实际上,我们观察到该请求成功返回hello world 。 但是,如果不使用cacert选项, 则会收到错误消息:
curl --key client.key --cert client.crt https://localhost:3000
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: https://curl.haxx.se/docs/sslcerts.htmlcurl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
On the other hand, if we leave off the key and cert options, we get a different error:
另一方面,如果我们省略了key和cert选项,则会得到另一个错误:
curl --cacert ca.crt https://localhost:3000
curl: (56) OpenSSL SSL_read: error:1409445C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required, errno 0
Wrap Up
结语
Nothing spectacularly new here. At the same time, hope you learned something.
这里没有什么新奇的东西。 同时,希望您能学到一些东西。
翻译自: https://codeburst.io/mutual-tls-authentication-mtls-de-mystified-11fa2a52e9cf
tls证书验证