我想通过API使用PHP / MySQL通过两个身份验证因素公开服务。一个因素是简单的用户名和密码。对于另一个因素,我尝试使用相互TLS,其中客户端证书与用户名匹配。我打算使用我在CentOS机器上设置的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发布的吗?
答案 0 :(得分:1)
有两点。
在这种情况下(通过证书进行客户端身份验证),服务器要么维护它信任的证书列表,要么CA签署这些证书。服务器将检查所提供的证书是否属于这两种情况之一。
对于提供的证书,任何人都不能提供任何证书,因为TLS交换将强制客户端使用相关私钥执行某些操作,因此服务器将能够验证客户端确实具有相关的私钥。公开证书。
我在https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake对此进行了详细解释,我在此总结:
当然,只有当您过滤最终客户端证书时,这一切才有效:如果您允许其中任何一个,任何人都可以创建一个具有任何可用功能的身份证明。
答案 1 :(得分:0)
配置Apache以允许相互认证非常简单,并且http://httpd.apache.org上的文档也很清楚。基本上,您需要两个证书:一个服务器要安装在Apache服务器上,然后一个客户端要安装在Firefox浏览器或客户端应用程序或其他设备上。客户端证书必须由Apache服务器知道的CA之一颁发,以使身份验证成功。
该项目https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication实现了Apache SSL / TLS相互身份验证的完整配置