带有自生成 CA、证书和客户端/服务器的“未知 CA”

dgn*_*uff 1 c++ verification ssl openssl peer

我正在编写一个自定义客户端和服务器,我想通过公共 Internet 安全地进行通信,因此我想使用 OpenSSL 并让两端都进行对等验证以确保我的客户端不会被 MITM 误导,同样未经授权的客户端无法连接到服务器。

这是在 SSL_connect / SSL_accept 阶段从服务器收到的错误:

15620:error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:ssl\record\rec_layer_s3.c:1528:SSL alert number 48
Run Code Online (Sandbox Code Playgroud)

我在 Windows 10 下运行,使用 OpenSSL 1.1.1。我正在使用以下批处理文件来创建它们。出于显而易见的原因,我手动输入了 ca 私钥密码。

openssl genrsa -out -des3 ca.key.pem 2048
openssl genrsa -out server.key.pem 2048
openssl genrsa -out client.key.pem 2048

openssl req -x509 -new -nodes -key ca.key.pem -sha256 -days 365 -out ca.cert.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=Foobar

openssl req -new -sha256 -key server.key.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=Foobar -out server.csr
openssl x509 -req -in server.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out server.cert.pem -days 365 -sha256

openssl req -new -sha256 -key client.key.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=Foobar -out client.csr
openssl x509 -req -in client.csr -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -out client.cert.pem -days 365 -sha256
Run Code Online (Sandbox Code Playgroud)

这里的目的是创建一个自签名 CA,然后直接对客户端和服务器密钥进行签名。

ca.key.pem 将存储在一个安全的地方:在一个加密的 veracrypt 卷上。

客户端和服务器都使用以下调用来启用对等验证:

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
Run Code Online (Sandbox Code Playgroud)

我相当确定这是一个证书问题,因为如果我删除该行,错误就会消失。

dgn*_*uff 6

自己回答这个问题,以便它可以帮助可能到达这里寻找此问题解决方案的任何其他人。答案在另一个 SO 问题中找到,但值得在这里重复:CA 的通用名称不能与客户端和服务器证书的通用名称相同。

因此将批处理文件的第四行更改为:

openssl req -x509 -new -nodes -key ca.key.pem -sha256 -days 365 -out ca.cert.pem -subj /C=US/ST=CA/L=Somewhere/O=Someone/CN=FoobarCA

解决了这个问题。

  • 感谢。上帝。我的疏忽,却完全犯了同样的错误。 (2认同)

Ste*_*ich 5

$ openssl req -x509 -new ... -addext basicConstraints=critical,CA:TRUE 
Run Code Online (Sandbox Code Playgroud)

这本质上创建了一个具有 2 个基本约束CA:TRUE扩展的证书:

$ openssl x509 -in ca.cert.pem -text
    X509v3 extensions:
        ...
        X509v3 Basic Constraints: critical
            CA:TRUE
        X509v3 Basic Constraints: critical
            CA:TRUE
Run Code Online (Sandbox Code Playgroud)

尝试使用CA来验证服务器证书将不起作用:

$ openssl verify -CAfile ca.cert.pem server.cert.pem 
C = XX, ST = XX, L = XX, O = XX, CN = CA
error 24 at 1 depth lookup: invalid CA certificate
error server.cert.pem: verification failed
Run Code Online (Sandbox Code Playgroud)

鉴于这个简单的检查不起作用,客户端也将无法验证服务器证书,从而导致警报unknown ca

...:tlsv1 alert unknown ca:...
Run Code Online (Sandbox Code Playgroud)

跳过时,-addext它将创建一个如文档所述的自签名证书,该证书已经具有CA:TRUE

$ openssl req -x509 -new ... 
...
$ openssl x509 -in ca.cert.pem -text
    X509v3 extensions:
        ...
        X509v3 Basic Constraints: critical
            CA:TRUE
Run Code Online (Sandbox Code Playgroud)

并使用它来验证服务器证书是否有效:

$ openssl verify -CAfile ca.cert.pem server.cert.pem 
server.cert.pem: OK
Run Code Online (Sandbox Code Playgroud)

该证书也应该由您的客户成功验证,因此不再产生unknown ca.