如您所见,您可以使用来在Apache Httpd中的SSL / TLS握手级别禁用证书验证SSLVerifyCLient optional_no_ca
。
您要面对的第二个问题是让客户端发送证书。由于您的证书不打算包含在PKI中,因此它们可以是自签名的,并具有各种颁发者。
当请求客户端证书时,服务器在握手期间向客户端发送CertificateRequest
TLS消息。此消息包含certificate_authorities
列表:
可接受的证书颁发机构的专有名称列表。这些专有名称可以为根CA或从属CA指定所需的专有名称。因此,此消息可用于描述已知根和所需授权空间。如果certificate_authorities列表为空,则客户端可以发送任何具有适当ClientCertificateType的证书,除非有相反的外部安排。
浏览器使用它来选择要发送的客户端证书(如果有)。
(请注意,有关空列表的部分仅在TLS 1.1及更高版本的规范中。SSL3.0和TLS 1.0在此方面保持沉默,实际上,它也将起作用。)
您有两种选择。
如果您期望的客户端证书将是自签名的,则它们都将具有不同的颁发者。因为您不知道会发生什么,所以服务器将需要发送一个空列表。为此,请使用SSLCADNRequestFile
指令并将其指向仅包含一个空行的文件(如果我没记错,它不适用于完全空的文件)。
第二个(不太干净)选项。将就您期望的所有客户端证书通用的颁发者DN达成一致,无论它们是否确实由该CA证书颁发(或该CA甚至不存在)。这样,您将大大破坏PKI模型(更多)。
如果您同意类似的发卡行DN CN=Dummy CA
(例如)。任何人都可以使用CN=Dummy CA
主题DN(和颁发者DN)(可能具有不同的密钥)来构建自签名证书。尽管该SSLCADNRequestFile
指令期望配置有证书来构建列表,但是这些证书根本不用于验证客户端证书,这只是配置certificate_authorities
列表的一种复杂方式(在其他指令的上下文中很自然)。如果您作为一项服务,将带有这些名称的自签名证书放在中SSLCADNRequestFile
,这将使CertificateRequest
TLS消息CN=Dummy CA
在certificate_authorities
列表中使用(在此阶段,这些名称只是名称,而不是证书)。然后,客户将能够使用发卡行DN领取自己的证书CN=Dummy CA
,无论其签名是否可以通过该证书(相同的密钥)进行验证,因为这些步骤中始终不涉及签名验证。
话虽这么说,请记住,使用时SSLVerifyCLient optional_no_ca
,不会进行真正的证书验证(我想您可以检查SSL_CLIENT_VERIFY
变量,如果您的手动验证只是您已经配置的PKI的后备解决方案)。在此阶段,您将只知道客户端具有它所提交的公钥证书的私钥(由TLS CertificateVerify
消息保证):如果要对某些证书进行身份验证,则需要执行某种形式的验证分类。(您不能信任证书的任何内容,即证书的公钥与其包含的名称/属性之间的任何绑定。)
这对于文件来说效果不佳,但是您可以对应用程序执行此操作(例如,如果您将证书传递给代理的Java服务器,则可以是PHP / CGI / ...甚至Java)。一种基本方法是拥有一个已知的公钥列表,或者您可以查看FOAF + SSL / WebID中的想法。