代码之家  ›  专栏  ›  技术社区  ›  Michael E. Mall

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

  •  0
  • Michael E. Mall  · 技术社区  · 6 年前

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

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

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

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

    相反,他们说Apache确认证书是由CA证书签名的。他们还解释了如何使用PHP访问证书中的字段,如SSL\u CLIENT\u S\u DN\u Email和SSL\u CLIENT\u M\u SERIAL,并使用它们确认证书属于消息的发送方。但是,我不清楚他们不仅仅使用公共证书中的信息。因此,任何可以访问公共证书的人都可以使用它作为身份验证的因素之一来对服务进行身份验证。如果是,这意味着它实际上不是身份验证的一个因素。

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

    2 回复  |  直到 6 年前
        1
  •  1
  •   Patrick Mevzek James Dean    5 年前

    有两点。

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

    对于所提供的证书,任何人都不能提供任何证书,因为TLS交换将要求客户端使用相关的私钥进行操作,因此服务器将能够验证客户端是否确实拥有所提供的公共证书的相关私钥。

    这一点在以下网站上有很好的解释: https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake 我总结如下:

    1. 与我们讨论无关的其他步骤
    2. 客户机用包含客户机证书的证书消息进行响应。
    3. ClientKeyExchange步骤 ,我们可以在讨论中跳过
    4. 客户端发送一个CertificateVerify消息,该消息是使用客户端证书的私钥对之前握手消息的签名。可以使用客户端证书的公钥来验证此签名。这让服务器知道客户端可以访问证书的私钥,从而拥有证书。 因此,在这里您可以看到客户机需要对其私钥执行一些操作,服务器将能够验证这一点。

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

        2
  •  0
  •   Antonio Musarra    6 年前

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

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