客户端证书认证 - Apache2

客户端证书认证 - Apache2

我正在尝试为我的一个应用程序设置客户端身份验证,但目前尚未成功。我为我的域名 *.example.com 购买了 Gandi 通配符 SSL 证书,以下是 apache2 服务器上的配置:

在 /etc/apache2/ssl 中我有以下文件:

  • example.crt => 证书
  • example.csr => 证书签名请求
  • example.key => 私钥
  • example.pem => 中级证书(gandi 给我的)

这是我的虚拟主机配置:

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
            ServerName www.example.com
            ServerAdmin [email protected]

            DocumentRoot /var/www/example/

            ErrorLog ${APACHE_LOG_DIR}/error-https.log
            CustomLog ${APACHE_LOG_DIR}/access-https.log combined

            SSLEngine on
            SSLCertificateFile /etc/apache2/ssl/example.crt
            SSLCertificateKeyFile /etc/apache2/ssl/example.key
            SSLCACertificateFile /etc/apache2/ssl/example.pem

            SSLVerifyClient require
            SSLVerifyDepth 2
            SSLOptions +StdEnvVars
    </VirtualHost>

现在,这是我创建客户端证书的过程:

在服务器上:

openssl genrsa -out client.key 2028

openssl req -new -key client.key -out client.csr

openssl x509 -sha256 -req -in client.csr -out client.crt -CA /etc/apache2/ssl/example.crt -CAkey /etc/apache2/ssl/example.key -CAcreateserial -days 1095

为了确保其正常工作,我将“client.*”文件传输到另一台私人服务器上,并使用 curl 创建了这个 php 脚本来测试连接:

<?php

$url = "https://www.example.com/api/client/";

$keyFile = "/etc/apache2/conf/certs/client.key";
$certFile = "/etc/apache2/conf/certs/client.crt";
$certPass = "";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, true);

curl_setopt($ch, CURLOPT_SSLKEY, $keyFile);
curl_setopt($ch, CURLOPT_SSLCERT, $certFile);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $certPass);

curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_HEADER,true);

$result=curl_exec($ch);
curl_close($ch);

var_dump($result);
die();

结果如下:

*   Trying IP.AD.DR.RES ...
* TCP_NODELAY set
* Connected to www.example.com (IP.AD.DR.RES) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
* Curl_http_done: called premature == 1
* stopped the pause stream!
* Closing connection 0
bool(false)

这就是我遇到的问题。在 curl 的调试消息中,我可以看到我的证书颁发机构未知。这两行看起来很奇怪:

*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs

因为它与我的虚拟主机配置不匹配。

感谢您的帮助 !

答案1

我确信这个问题已经被回答过很多次了。

目录文件路径分析分别是根 CA 文件及其路径由 curl 使用基本上,这包含了您的客户端向外部系统进行身份验证时要检查的所有根 CA 文件。

检查 CA(认证机构)以获取您用于向 Apache 服务器进行身份验证的客户端证书。然后,您需要检查该证书是否在您的 CA 列表(CAfile)中。

答案2

您为 Apache 提供了错误的文件。 应该SSLCertificateFile指向您的服务器将向任何使用 SSL 的用户提供的证书,因此在您的情况下,它应该是文件example.pemSSLCertificateKeyFile是服务器用于 SSL 通信的密钥文件,因此它应该是证书的密钥example.pem。 这些与客户端身份验证完全无关。

SSLCACertificateFile是应该颁发客户端证书的 CA 证书,因此它应该是example.crt您情况下的文件。

相关内容