使用OpenSSL测试SSL/TLS客户端身份验证

27

我正在开发一个使用TLS的客户端/服务器应用程序。我的想法是在客户端上使用证书,以便服务器对其进行身份验证。同时,在服务器上使用另一个证书,使得客户端也能够验证它连接到了正确的服务器。

我想先测试并使用openssl的s_servers_client来验证这个提议。

到目前为止,我已经在服务器上创建了CA私钥,并创建了一个根证书。使用根证书签署了两个CSR,以获得一个用于服务器的证书和一个用于客户端的证书。

我还在客户端安装了客户端证书+根证书,以及在服务器上安装了服务器证书+根证书。

现在我想尝试建立openssl的s_servers_client之间的连接,并验证它们都得到了相互身份验证,但我无法理解文档中如何做到这一点。有什么帮助或指南吗?

一旦我设置好了,下一步就是测试自己开发的客户端与该服务器,以及我们自己开发的服务器与s_client之间的情况。我们可以用它来测试吗?

谢谢

2个回答

45

看起来你正在尝试使用 s_clients_server 进行测试,建立一个根信任(root of trust);或者在你的代码中使用 OpenSSL 编程方式。


为确保 openssl s_client(或 openssl s_server )使用你的根信任,请使用以下选项:

  • -CAfile 选项指定根证书
  • -cert 选项指定要使用的证书
  • -key 选项指定证书的私钥

有关详细信息,请查看s_client(1)s_server(1)文档。


要在客户端上以编程方式执行相同操作,您应该使用:

  • SSL_CTX_load_verify_locations 加载受信任的根证书
  • SSL_CTX_use_certificate 指定客户端证书
  • SSL_CTX_use_PrivateKey 加载客户端证书的私钥

要在服务器上以编程方式执行相同操作,则应该使用:

  • SSL_CTX_load_verify_locations 加载受信任的根证书
  • SSL_CTX_use_certificate_chain_file 指定服务器证书
  • SSL_CTX_use_PrivateKey 加载服务器证书的私钥
  • SSL_CTX_set_client_CA_list 告诉客户端发送其客户端证书

如果你不想为每个连接使用参数(即常见上下文),则可使用例如 SSL_use_certificateSSL_use_PrivateKey 为每个 SSL 连接设置。

很多事情都要在SSL_CTX_set_client_CA_list中进行。它(1) 加载服务器用于验证客户端的CA,(2) 导致服务器发送一份接受的CA列表以验证客户端,并且(3) 如果客户端拥有满足服务器所接受的CA列表的证书,则会触发客户端证书消息ClientCertificate
还可以参考SSL_CTX_load_verify_locations(3)SSL_CTX_use_certificate(3)SSL_CTX_set_client_CA_list和相关文档。
最易使用的证书和密钥格式是PEM格式,例如使用-----BEGIN CERTIFICATE-----。对于服务器证书,请确保文件是服务器证书和任何中间证书的串联,以便客户端构建完整链路。
服务器发送所有必需证书是解决“哪个目录”问题的标准做法。这是PKI中已知的问题,本质上是客户端不知道去哪里获取缺失的中间证书。
总体而言,您现在知道需要使用的函数。下载像nginx这样的小服务器,看看生产服务器如何实际使用它们。您甚至可以使用自带SSL/TLS服务器的SQL服务器,例如Postgres。只需搜索源文件中的SSL_CTX_load_verify_locationsSSL_load_verify_locations,您就会找到正确的位置。

虽然我不建议这样做,但你甚至可以查看s_client.cs_server.c。它们位于<openssl dir>/apps中。但有时候该代码可能难以阅读。


1
非常感谢您的回答!这个答案非常棒!让我感到遗憾的是我不能给它投两次票! - Siu Ching Pong -Asuka Kenji-

4

生成两对证书/密钥,一对用于服务器,一对用于客户端。同时创建test.txt文件并写入任何内容。

要设置一个SSL服务器,并检查客户端证书,请运行以下命令:

openssl s_server -cert server_cert.pem -key server_key.pem -WWW -port 12345 -CAfile client_cert.pem -verify_return_error -Verify 1

要使用客户端证书测试服务器,请运行以下命令:

echo -e 'GET /test.txt HTTP/1.1\r\n\r\n' | openssl s_client -cert client_cert.pem -key client_key.pem -CAfile server_cert.pem -connect localhost:12345 -quiet

或者您可以使用curl命令:

curl -k --cert client_cert.pem --key client_key.pem https://localhost:12345/test.txt

运行第一个命令时,我得到了以下信息:[验证深度为1,必须返回证书输入服务器私钥.pem的密码:使用默认临时DH参数接受],此时命令卡住了。这是表示我的客户端证书已经成功验证了吗?还是出现了某些错误? - Sparsh Dutta
@SparshDutta,您可能需要输入服务器证书密码。 - anton_rh
我已经输入了服务器证书密码。 - Sparsh Dutta
我需要创建一个信任库并将我的客户端证书添加到服务器信任库中吗? - Sparsh Dutta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接