如果使用多个颁发者证书完成,则 openssl 验证失败

openssl verify fails if done with multiple issuer certificates

我生成了ca.crt,我ca.crt和server.crt。这里给出了证书的一些细节。

$ openssl x509 -in server.crt -noout -issuer -subject
issuer=CN = my-ica
subject=CN = server

$ openssl x509 -in ica.crt -noout -issuer -subject
issuer=CN = my-ca
subject=CN = my-ica

$ openssl x509 -in ca.crt -noout -issuer -subject
issuer=CN = my-ca
subject=CN = my-ca

我验证了 ca 颁发了 ica 和 ica 颁发了服务器证书。

# Verifies ca issued ica.
$ openssl verify -verbose -CAfile ca.crt ica.crt
ica.crt: OK

# Verifies ica issued server as the error is at depth 1.
$ openssl verify -verbose -CAfile ica.crt server.crt
CN = my-ica
error 2 at 1 depth lookup: unable to get issuer certificate
error server.crt: verification failed

第一个问题:现在当我尝试根据this highly upvoted answer一次验证整个链时,它失败了。

$ openssl verify -verbose -CAfile <(cat ica.crt ca.crt) server.crt
CN = my-ica
error 24 at 1 depth lookup: invalid CA certificate
error server.crt: verification failed

第二个问题:即使我尝试按照建议here检查部分链,即使那样也失败了。

$ openssl verify -verbose -no-CAfile -no-CApath -partial_chain -trusted ica.crt server.crt
CN = my-ica
error 24 at 1 depth lookup: invalid CA certificate
error server.crt: verification failed

以上两种方法我做错了什么?
如果有帮助,这就是生成证书的方式:

openssl req \
  -new \
  -x509 \
  -nodes \
  -days 365 \
  -subj '/CN=my-ca' \
  -keyout ca.key \
  -out ca.crt
openssl genrsa \
  -out ica.key 2048
openssl req \
  -new \
  -key ica.key \
  -subj '/CN=my-ica' \
  -out ica.csr
openssl x509 \
  -req \
  -in ica.csr \
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -days 365 \
  -extfile <(printf "subjectAltName=DNS:localhost,DNS:*.localhost") \
  -out ica.crt
openssl genrsa \
  -out server.key 2048
openssl req \
  -new \
  -key server.key \
  -subj '/CN=server' \
  -out server.csr
openssl x509 \
  -req \
  -in server.csr \
  -CA ica.crt \
  -CAkey ica.key \
  -CAcreateserial \
  -days 365 \
  -extfile <(printf "subjectAltName=DNS:localhost,DNS:*.localhost") \
  -out server.crt

问题是您的中间 CA ica.crt 根本不是 CA。它缺少 basicConstraints=critical,CA:TRUE 作为扩展名。这意味着 ica.crt 只是叶证书,不应用于签署其他证书。

虽然 openssl 在使用没有此类扩展的证书进行签名时不会抱怨,但它将无法构建信任链,因为 ica.crt 不是 server.crt 的有效颁发者,因为缺少 CA:TRUE 约束。

添加约束使一切正常,即

openssl x509 \
  -req \
  -in ica.csr \
  ...
  -extfile <(printf "subjectAltName=DNS:localhost,DNS:*.localhost\nbasicConstraints=critical,CA:TRUE") \
  -out ica.crt

查看证书显示它现在有相关标志:

$ openssl x509 -in ica.crt -text -noout
...
        X509v3 extensions:
            ...
            X509v3 Basic Constraints: critical
                CA:TRUE

并在验证工作中使用此证书:

$ openssl verify -verbose -CAfile <(cat ica.crt ca.crt) server.crt
server.crt: OK