我想让我的用户能够使用他们自己的个人 x.509 证书登录。用户向我(帐户注册脚本)提供他/她的 x.509 公钥。Apache 应该只接受已知公钥(在类似于 .htpasswd 的文件中指定)并拒绝其他公钥。我必须如何配置 apache 才能实现这一点?
我试过谷歌,但只找到了 CA 签名的 x.509 证书的解决方案。CA 对于这个问题毫无意义。即使是自签名的 x.509,如果知道其公钥,也应该能够登录。
答案1
您可以使用所有客户端证书创建一个 CA 文件,这应该可以工作。
但是,您将不再能够信任证书 CN 来验证不同的用户。
如果您不想重新启动 Apache,仍然可以通过使用 CA 目录而不是 CA 包以及 SSLCACertificatePath 指令来执行此操作(您需要符号链接或重命名您的证书,以便可以通过哈希访问它们)
答案2
您可以这样做,Apache Httpd 中没有用于常规身份验证的任何东西。您需要在应用程序中编写一些代码来处理此问题(即在 PHP/CGI/Java 层中执行身份验证):不幸的是,这或多或少排除了纯文件(HTML、JS 等)。
为此,
- 使用
SSLVerifyClient optional_no_ca
允许接受任何证书(就 Apache Httpd 的 SSL/TLS 层而言); - 观点
SSLCADNRequestFile
发送到只有空行的文件:这将使CertificateRequest
发送成为空certificate_authorities
列表,这将向客户端表明它可以发送任何内容(并不保证服务器会接受它)。TLS 1.1 明确允许此行为(以前的版本对此没有说明)。实际上,它适用于大多数浏览器的 SSLv3 和 TLS 1.0。
这将允许在 SSL/TLS 握手期间出示和接受任何证书。不幸的是,这也会删除 Apache Httpd 所做的任何身份验证,因此验证 CN 或证书其他部分的任何指令都没有任何用处(因为您不能信任证书的内容)。
在此阶段,您所知道的只是客户端拥有所提供证书中公钥的私钥(否则CertificateVerify
TLS 步骤将失败)。您甚至不能信任该证书的主体。此证书将位于SSL_CLIENT_CERT
。您必须有一些代码来读取它并提取其公钥,然后再将其与已知的公钥列表进行比较。(mod_proxy
例如,如果您将此客户端证书传递给后端 Java 服务器,这也可以工作。)PHP、Perl、Python、Java(选择您喜欢的语言)中有库可以分析证书的内容,但这需要一些编程,并且当然只会验证由此类应用程序处理的请求。