如何使apache请求客户端SSL证书,而无需根据已知的CA对其进行验证?


9

我正在使用apache2(2.2.3)为我希望客户使用证书进行身份验证的网站提供服务。由于我只需要验证提供特定证书的用户是否与过去提交该证书的用户相同,因此签署该证书的CA无关紧要。但是,似乎使用SSLVerifyClient requirerequire SSLCACertificateFile ...(或SSLCACertificatePath ...),然后apache将仅接受该文件/路径中由CA签名的证书。有没有一种方法可以使apache接受任何客户端证书,而与颁发/发行CA无关。(即验证客户是否具有与显示的公钥相对应的私钥,但不必费心验证签发/签名的CA)


您如何计划跟踪已认证的证书?
Shane Madden

@ShaneMadden:类似于将证书映射到内部用户ID的表。公钥加密的机制将取代密码交换。
艾萨克(Isaac)

2
是的-我要说的是Apache没有一个将证书映射到内部用户ID的表。如果要让用户通过客户端证书进行身份验证,为什么不给用户签名的证书?正如您已经提到的,有一些OpenID提供程序可以做到这一点。Apache的mod_ssl设计旨在根据证书签名关系对用户进行身份验证;如果您出于某种原因不愿意这样做,则需要在自己的代码中实施证书身份验证,该代码还可以处理证书到用户的映射。
Shane Madden '04年

@ShaneMadden:我希望避免颁发证书,如果我仅接受我颁发的证书,则基于智能卡的证书就会消失。不管我做什么,系统的某些部分都将在应用程序级别进行,但是由于那里有所有的mod_ssl机器,我希望它可以为我完成一些工作。
艾萨克(Isaac)

1
@ShaneMadden的优点之一optional_no_ca是它对UI更好,因为如果证书有问题,您可以显示HTTP错误消息(否则就不能显示,因为不良的客户端证书会在HTTP层之前停止连接) )。如果您想尝试其他方法来验证证书(例如WebID),它也很有用。没错,不过您希望进行某些验证,并且只有在代码(例如,在PHP / CGI / Java中)通过代码处理请求时才真正起作用,而对于文件则不需要那么多。
布鲁诺

Answers:


10

如您所见,您可以使用来在Apache Httpd中的SSL / TLS握手级别禁用证书验证SSLVerifyCLient optional_no_ca

您要面对的第二个问题是让客户端发送证书。由于您的证书不打算包含在PKI中,因此它们可以是自签名的,并具有各种颁发者。

当请求客户端证书时,服务器在握手期间向客户端发送CertificateRequestTLS消息。此消息包含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,这将使CertificateRequestTLS消息CN=Dummy CAcertificate_authorities列表中使用(在此阶段,这些名称只是名称,而不是证书)。然后,客户将能够使用发卡行DN领取自己的证书CN=Dummy CA,无论其签名是否可以通过该证书(相同的密钥)进行验证,因为这些步骤中始终不涉及签名验证。

话虽这么说,请记住,使用时SSLVerifyCLient optional_no_ca,不会进行真正的证书验证(我想您可以检查SSL_CLIENT_VERIFY变量,如果您的手动验证只是您已经配置的PKI的后备解决方案)。在此阶段,您将只知道客户端具有它所提交的公钥证书的私钥(由TLS CertificateVerify消息保证):如果要对某些证书进行身份验证,则需要执行某种形式的验证分类。(您不能信任证书的任何内容,即证书的公钥与其包含的名称/属性之间的任何绑定。)

这对于文件来说效果不佳,但是您可以对应用程序执行此操作(例如,如果您将证书传递给代理的Java服务器,则可以是PHP / CGI / ...甚至Java)。一种基本方法是拥有一个已知的公钥列表,或者您可以查看FOAF + SSL / WebID中的想法。


2

使用SSLVerifyCLient optional_no_ca(而不是require)会导致apache不检查发出证书的CA(因此不需要CA证书文件或路径)。它确实允许客户端/用户不提交证书,因此必须单独检查是否使用了证书。

(显然,我只是没有仔细阅读mod_ssl文档。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.