用于身份验证的 Apache 客户端证书



我想通过API公开一个服务,使用PHP/MySQL进行两个身份验证因素。 一个因素是简单的用户名和密码。 对于另一个因素,我正在尝试使用双向TLS,其中客户端证书与用户名匹配。 我打算使用我在 CentOS 盒子上与 Apache 一起设置的 CA 的自签名证书,并通过安全通道向客户颁发客户端证书以及私钥。

我找到了一些关于如何使用SSL证书设置用户身份验证的体面文章。 到目前为止,我发现的最好的如下。

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

但是,在向我解释某些事情方面,这篇文章和其他文章似乎有一个漏洞。 我如何设想这种工作是,当客户端发出 POST 请求以及用户名和密码时,还包括一个证书,其中包含由颁发给用户的私钥签名的数字签名。 然后,公钥可以解密此签名,以确认私钥的所有者发送了消息。 但是,这些文章实际上并没有证实这是正在发生的事情。

相反,他们说Apache确认证书是由CA Cert签署的。 他们还解释了如何使用 PHP 访问证书中的字段,例如 SSL_CLIENT_S_DN_Email 和 SSL_CLIENT_M_SERIAL,并使用它们来确认证书属于消息的发件人。 但是,我不清楚他们是否只是使用公共证书中的信息。 因此,可以访问公共证书的任何人都可以将其用作身份验证因素之一,以对服务进行身份验证。 如果是这样,这意味着它实际上不是身份验证因素。

我是否错误地认为我希望的情况 - 消息中包含的证书确实包括由颁发给用户的私钥签名的签名,并且 Apache 使用公钥解密签名,而不仅仅是确认证书是由 CA 颁发的?

有两点。

在这种情况下(通过证书进行客户端身份验证(,服务器要么维护它信任的证书列表,要么维护对这些证书进行签名的 CA。服务器将检查所提供的证书是否属于这两种情况之一。

至于提供的证书,不是任何人都可以提供任何证书,因为TLS交换将要求客户端使用关联的私钥做一些事情,因此服务器将能够验证客户端是否确实具有所提供公共证书的相关私钥。

这在以下位置得到了很好的解释: https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake 我在这里总结

  1. 与我们的讨论无关的其他步骤
  2. 客户端
  3. 使用包含客户端证书的证书消息进行响应。
  4. 客户端密钥交换步骤,我们可以在讨论中跳过
  5. 客户端发送 CertificateVerify 消息,该消息是使用客户端证书私钥对上一个握手消息的签名。可以使用客户端证书的公钥验证此签名。这让服务器知道客户端可以访问证书的私钥,从而拥有证书。所以在这里你看到客户端需要用它的私钥做一些事情,服务器将能够验证这一点。

当然,只有当您过滤最终客户端证书时,这一切才有效:如果您允许其中任何一个,任何人都可以使用任何身份创建一个有效的证书。

配置 Apache 以允许相互身份验证非常简单,有关 http://httpd.apache.org 的文档非常清楚。 基本上,您需要两个证书:服务器一个安装在Apache服务器上,然后是客户端证书,安装在Firefox浏览器或客户端应用程序或其他设备上。 客户端证书必须由 Apache 服务器知道的 CA 之一颁发,身份验证才能成功。

该项目 https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication 实现了Apache SSL/TLS相互身份验证的完整配置

最新更新