简体   繁体   English

Apache客户端认证证书

[英]Apache Client Certificates for Authentication

I want to expose a service via an API with two factors of authentication using PHP/MySQL. 我想通过使用PHP / MySQL进行身份验证的两个因素通过API公开服务。 One factor is a simple user name and password. 一个因素是简单的用户名和密码。 For the other factor, I am attempting to use mutual TLS, in which the client certificate is matched with the username. 对于另一个因素,我尝试使用双向TLS,其中客户端证书与用户名匹配。 I intend to use self-signed certificates from a CA I set up on a CentOS box with Apache and issue the client certificates to customers via a secure channel, along with the private keys. 我打算使用我在CentOS机器上与Apache一起建立的CA的自签名证书,并通过安全通道将客户证书和私钥一起颁发给客户。

I found some decent articles on how to set up user authentication using SSL certificates. 我发现了一些有关如何使用SSL证书设置用户身份验证的不错的文章。 The best I found so far is below. 我到目前为止发现的最好的是下面的。

https://cweiske.de/tagebuch/ssl-client-certificates.htm https://cweiske.de/tagebuch/ssl-client-certificates.htm

But, there seems to be a hole this and the other articles in terms of explaining something to me. 但是,在向我解释某些内容方面,该文章和其他文章似乎存在漏洞。 How I envision this working is that when a POST request is made by the client, along with the user name and password, a certificate with a digital signature signed by the private key issued to the user is also included. 我如何设想这种工作方式是:当客户端发出POST请求时,连同用户名和密码一起,还将包括带有由数字签名所颁发给用户的带有数字签名的证书。 This signature can then be decrypted by the public key to confirm that the owner of the private key sent the message. 然后可以使用公钥解密此签名,以确认私钥的所有者已发送消息。 But, these articles don't actually confirm that this is what is happening. 但是,这些文章实际上并没有确认这是正在发生的事情。

Instead, they say that Apache confirms the certificate was signed by the CA Cert. 相反,他们说Apache确认证书是由CA Cert签名的。 They also explain how to use PHP to access the fields in the certificate, such as SSL_CLIENT_S_DN_Email and SSL_CLIENT_M_SERIAL, and use them to confirm the certificate belongs to the sender of the message. 他们还解释了如何使用PHP访问证书中的字段,例如SSL_CLIENT_S_DN_Email和SSL_CLIENT_M_SERIAL,并使用它们来确认证书属于消息的发件人。 But, it is not clear to me that they are not just using information in the public certificate. 但是,对我来说不清楚他们是否只是在使用公共证书中的信息。 So, anyone who can access the public certificate can then use it as one of the factors of authentication to authenticate to the service. 因此,任何可以访问公共证书的人都可以将其用作身份验证因素之一,以对服务进行身份验证。 If so, this means it is not really a factor of authentication. 如果是这样,则意味着它并不是真正的认证因素。

Am I mistaken to think what I hope is the case - that the certificate included with the message does include a signature signed by the private key issued to the user and that Apache decrypts the signature with the public key rather than just confirm the certificate was issued by the CA? 我是否误以为是我希望的情况-消息中包含的证书确实包含由颁发给用户的私钥签名的签名,并且Apache用公钥解密了签名,而不仅仅是确认证书已颁发由CA?

There are two points. 有两点。

In cases like that (client authentication by certificate) the server either maintains a list of certificates it trusts or CAs signing those certificates. 在这种情况下(通过证书进行客户端身份验证),服务器将维护其信任的证书列表或对这些证书进行签名的CA。 A check will be made by the server that the certificate presented is in one of these two cases. 服务器将检查这两种情况之一中提供的证书。

As for the certificate presented, not anyone can present any certificate, because the TLS exchange will mandate the client to do something with the associated private key, hence the server will be able to verify the client has indeed the relevant private key for the public certificate presented. 至于所提供的证书,没有人可以提供任何证书,因为TLS交换将强制客户端使用关联的私钥进行操作,因此服务器将能够验证客户端确实具有公共证书的相关私钥。呈现。

This is well explained at: https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake which I summarize here: 在以下网址对此进行了很好的说明: https : //en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake ,我在这里总结:

  1. other steps not relevant for our discussion 与我们的讨论无关的其他步骤
  2. The client responds with a Certificate message, which contains the client's certificate. 客户端以“证书”消息作为响应,其中包含客户端的证书。
  3. ClientKeyExchange step , that we can skip in our discussion ClientKeyExchange步骤 ,我们可以在讨论中跳过
  4. The client sends a CertificateVerify message, which is a signature over the previous handshake messages using the client's certificate's private key. 客户端发送一个CertificateVerify消息,该消息是使用客户端证书的私钥对先前握手消息进行的签名。 This signature can be verified by using the client's certificate's public key. 可以使用客户端证书的公共密钥来验证此签名。 This lets the server know that the client has access to the private key of the certificate and thus owns the certificate. 这使服务器知道客户端可以访问证书的私钥,因此拥有证书。 So here you see the client needs to do something with its private key, and the server will be able to verify that. 因此,在这里您可以看到客户端需要使用其私钥进行某些操作,服务器将能够对此进行验证。

Of course this all work only if you filter the end client certificates: if you allow any of them, anyone can create one with any identity that will work. 当然,仅当您过滤最终客户证书时,所有这些方法才有效:如果允许其中的任何一个,则任何人都可以创建具有任何身份的证书。

Configuring Apache to allow mutual authentication is quite simple and the documentation on http://httpd.apache.org is quite clear. 配置Apache以允许相互认证非常简单,并且http://httpd.apache.org上的文档非常清晰。 Basically you need two certificates: the server one to install on the Apache server and then the client one, to be installed on your Firefox browser or client application or other device. 基本上,您需要两个证书:一个服务器要安装在Apache服务器上,然后一个客户端要安装在Firefox浏览器或客户端应用程序或其他设备上。 The client certificate must be issued by one of the CAs that the Apache server knows for authentication to succeed. 客户端证书必须由Apache服务器知道的CA之一颁发,以使身份验证成功。

This project https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication implements a complete configuration of Apache SSL / TLS Mutual Authentication 该项目https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication实现了Apache SSL / TLS相互认证的完整配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM