OpenSSL 验证:不同 OpenSSL 版本之间 "error 20 at 0 depth lookup: unable to get local issuer certificate"
OpenSSL verify: "error 20 at 0 depth lookup: unable to get local issuer certificate" between different OpenSSL versions
对于 OpenSSL 1.1.1(在 Ubuntu 18.04)与 OpenSSL 1.1.1f(在 Ubuntu 之间生成的证书链,我 运行 遇到了一个奇怪的验证错误20.04).
这是我的测试环境(都是 Docker 图片):
- docker 运行 -it ubuntu:18.04 /bin/bash
- docker 运行 -it ubuntu:20.04 /bin/bash
该方案涉及生成自签名根 CA,然后生成一个或多个颁发的证书。在 Ubuntu 18.04 实例上,结果看起来不错:
root@temp-ubuntu-0:/tmp/cert# openssl version
OpenSSL 1.1.1 11 Sep 2018
root@temp-ubuntu-0:/tmp/cert# openssl verify -CAfile root.cer client.cer
client.cer: OK
在 Ubuntu 20.04 上,出现“0 深度查找错误 20:无法获取本地颁发者证书”错误:
root@temp-ubuntu-20-0:/tmp/cert# openssl version
OpenSSL 1.1.1f 31 Mar 2020
root@temp-ubuntu-20-0:/tmp/cert# openssl verify -CAfile root-ca.cer client.cer
C = CA, ST = State, L = City, OU = POC, CN = client
error 20 at 0 depth lookup: unable to get local issuer certificate
error client.cer: verification failed
# Observed the same behaviour with OpenSSL 1.1.1g and 1.1.1i (from NGINX Docker images)
以下是采取的步骤:
mkdir -p /tmp/cert
cd /tmp/cert
# Create a ".rnd" file to avoid warnings
openssl rand -writerand ~/.rnd
# Create the root CA private key and certificate
openssl req \
-new \
-x509 \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root-ca.key \
-out root-ca.cer \
-days 3650 \
-subj '/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA' \
-addext "basicConstraints = CA:TRUE" \
-addext "subjectKeyIdentifier = hash" \
-addext "authorityKeyIdentifier = keyid:always, issuer:always" \
-addext "subjectAltName = DNS:POC Root CA" \
-addext "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly"
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the CSR
openssl req -in server.csr -text -noout
# Create the .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = serverAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in server.cer -text -noout
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the CSR
openssl req -in client.csr -text -noout
# Create the .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = clientAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in client.cer -text -noout
同样的问题发生在server.cer
;一个有效,另一个无效。
最终目标是在 NGINX 上配置 mTLS。服务器 TLS 部分似乎可以正常工作,但客户端认证身份验证 运行 正在进入未解决的问题,导致发现这种情况。希望这不仅仅是一条红鲱鱼。
非常感谢对此行为的任何见解!
谢谢!
如果将根 CA 拆分为 openssl req
/openssl x509
命令而不是根 CA 的单个 openssl req
命令,这似乎可行。感觉像是一个缺陷,但它确实有效。使用 OpenSSL 1.1.1f 在 Ubuntu 20.04 上测试。
这是一组新命令:
# Create the root CA CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root.key \
-out root.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA"
# Create the root CA .conf file
cat > /tmp/cert/root_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
EOF
# Create the root CA certificate
openssl x509 \
-req \
-sha256 \
-signkey root.key \
-in root.csr \
-out root.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/root_openssl.conf \
-extensions v3_attributes
# Use the AKS namespace name for the server certificate
export SERVER_NAME=echo-namespace-1
# Create the server CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the server CSR
openssl req -in server.csr -text -noout
# Create the server .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF
# Create the server certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new server certificate
openssl x509 -in server.cer -text -noout
# Verify the new server certificate against the root CA
openssl verify -CAfile root.cer server.cer
# Create the client CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the client CSR
openssl req -in client.csr -text -noout
# Create the client .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF
# Create the client certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new client certificate
openssl x509 -in client.cer -text -noout
# Verify the new client certificate against the root CA
openssl verify -CAfile root.cer client.cer
谢谢大家!
对于 OpenSSL 1.1.1(在 Ubuntu 18.04)与 OpenSSL 1.1.1f(在 Ubuntu 之间生成的证书链,我 运行 遇到了一个奇怪的验证错误20.04).
这是我的测试环境(都是 Docker 图片):
- docker 运行 -it ubuntu:18.04 /bin/bash
- docker 运行 -it ubuntu:20.04 /bin/bash
该方案涉及生成自签名根 CA,然后生成一个或多个颁发的证书。在 Ubuntu 18.04 实例上,结果看起来不错:
root@temp-ubuntu-0:/tmp/cert# openssl version
OpenSSL 1.1.1 11 Sep 2018
root@temp-ubuntu-0:/tmp/cert# openssl verify -CAfile root.cer client.cer
client.cer: OK
在 Ubuntu 20.04 上,出现“0 深度查找错误 20:无法获取本地颁发者证书”错误:
root@temp-ubuntu-20-0:/tmp/cert# openssl version
OpenSSL 1.1.1f 31 Mar 2020
root@temp-ubuntu-20-0:/tmp/cert# openssl verify -CAfile root-ca.cer client.cer
C = CA, ST = State, L = City, OU = POC, CN = client
error 20 at 0 depth lookup: unable to get local issuer certificate
error client.cer: verification failed
# Observed the same behaviour with OpenSSL 1.1.1g and 1.1.1i (from NGINX Docker images)
以下是采取的步骤:
mkdir -p /tmp/cert
cd /tmp/cert
# Create a ".rnd" file to avoid warnings
openssl rand -writerand ~/.rnd
# Create the root CA private key and certificate
openssl req \
-new \
-x509 \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root-ca.key \
-out root-ca.cer \
-days 3650 \
-subj '/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA' \
-addext "basicConstraints = CA:TRUE" \
-addext "subjectKeyIdentifier = hash" \
-addext "authorityKeyIdentifier = keyid:always, issuer:always" \
-addext "subjectAltName = DNS:POC Root CA" \
-addext "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly"
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the CSR
openssl req -in server.csr -text -noout
# Create the .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = serverAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in server.cer -text -noout
# Create the CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the CSR
openssl req -in client.csr -text -noout
# Create the .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
extendedKeyUsage = clientAuth
EOF
# Create the certificate
openssl x509 \
-req \
-sha256 \
-CA root-ca.cer \
-CAkey root-ca.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new certificate
openssl x509 -in client.cer -text -noout
同样的问题发生在server.cer
;一个有效,另一个无效。
最终目标是在 NGINX 上配置 mTLS。服务器 TLS 部分似乎可以正常工作,但客户端认证身份验证 运行 正在进入未解决的问题,导致发现这种情况。希望这不仅仅是一条红鲱鱼。
非常感谢对此行为的任何见解!
谢谢!
如果将根 CA 拆分为 openssl req
/openssl x509
命令而不是根 CA 的单个 openssl req
命令,这似乎可行。感觉像是一个缺陷,但它确实有效。使用 OpenSSL 1.1.1f 在 Ubuntu 20.04 上测试。
这是一组新命令:
# Create the root CA CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout root.key \
-out root.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/OU=Certificate Authorities/CN=POC Root CA"
# Create the root CA .conf file
cat > /tmp/cert/root_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly
EOF
# Create the root CA certificate
openssl x509 \
-req \
-sha256 \
-signkey root.key \
-in root.csr \
-out root.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/root_openssl.conf \
-extensions v3_attributes
# Use the AKS namespace name for the server certificate
export SERVER_NAME=echo-namespace-1
# Create the server CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout server.key \
-out server.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=server"
# Confirm the contents of the server CSR
openssl req -in server.csr -text -noout
# Create the server .conf file
cat > /tmp/cert/server_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:server
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF
# Create the server certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in server.csr \
-out server.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/server_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new server certificate
openssl x509 -in server.cer -text -noout
# Verify the new server certificate against the root CA
openssl verify -CAfile root.cer server.cer
# Create the client CSR and private key
openssl req \
-new \
-nodes \
-sha256 \
-newkey rsa:4096 \
-keyout client.key \
-out client.csr \
-subj "/C=CA/ST=State/L=City/OU=POC/CN=client"
# Confirm the contents of the client CSR
openssl req -in client.csr -text -noout
# Create the client .conf file
cat > /tmp/cert/client_openssl.conf << EOF
[ v3_attributes ]
basicConstraints = CA:FALSE
subjectAltName = DNS:client
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF
# Create the client certificate
openssl x509 \
-req \
-sha256 \
-CA root.cer \
-CAkey root.key \
-in client.csr \
-out client.cer \
-days 3650 \
-set_serial `date +%Y%m%d%H%M%S%N` \
-extfile /tmp/cert/client_openssl.conf \
-extensions v3_attributes
# Confirm the contents of the new client certificate
openssl x509 -in client.cer -text -noout
# Verify the new client certificate against the root CA
openssl verify -CAfile root.cer client.cer
谢谢大家!