【问题标题】:"unknown ca" with self-generated CA, certificates and client/server带有自生成 CA、证书和客户端/服务器的“未知 ca”
【发布时间】:2018-11-01 15:24:49
【问题描述】:

我正在编写一个自定义客户端和服务器,我想通过公共 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

我在 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

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

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

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

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);

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

【问题讨论】:

    标签: c++ ssl openssl verification peer


    【解决方案1】:

    我自己回答这个问题,以便它可以帮助任何可能到达这里的人寻找解决这个问题的方法。答案在另一个 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】:
    $ openssl req -x509 -new ... -addext basicConstraints=critical,CA:TRUE 
    

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

    $ openssl x509 -in ca.cert.pem -text
        X509v3 extensions:
            ...
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Basic Constraints: critical
                CA:TRUE
    

    尝试使用 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
    

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

    ...:tlsv1 alert unknown ca:...
    

    当跳过-addext 时,它将创建一个已记录的自签名证书,其中已经有CA:TRUE

    $ openssl req -x509 -new ... 
    ...
    $ openssl x509 -in ca.cert.pem -text
        X509v3 extensions:
            ...
            X509v3 Basic Constraints: critical
                CA:TRUE
    

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

    $ openssl verify -CAfile ca.cert.pem server.cert.pem 
    server.cert.pem: OK
    

    您的客户也应该成功验证此证书,因此不再导致unknown ca

    【讨论】:

    • 我已经编辑了问题以反映对此的响应情况,并且服务器仍在生成“未知 ca”错误。所以我还是有问题。是否到了我应该发布整个源而不是 sn-ps 的地步?
    • 找到了问题,在这个 SO 问题上:stackoverflow.com/questions/19726138/…。我或许应该避免用XX 替换-subj 选项中的参数,但这样做是因为我不想发布它们。也就是说,我对 CA 和两个密钥都使用了相同的 CN= 值,这显然是完全禁止的。
    • @dgnuff:它需要通过主题或授权密钥标识符(您没有)找到发行者,因此它不能具有相同的主题和发行者信息,除非主题和发行者相同.
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多