错误信息
error:05800074:x509 certificate routines::key values mismatch
也可能输出为
- x509 certificate routines:ossl_x509_check_private_key:key values mismatch
- [X509: KEY_VALUES_MISMATCH] key values mismatch
- code: 'ERR_OSSL_X509_KEY_VALUES_MISMATCH'
nginx -t 报告为“[emerg] SSL_CTX_use_PrivateKey(\"<key file>\") failed (SSL: error:05800074:x509 certificate routines::key values mismatch)”;openssl CLI 会加上函数名(“x509 certificate routines:ossl_x509_check_private_key:key values mismatch”);Python 输出“[X509: KEY_VALUES_MISMATCH] key values mismatch”;Node.js 设置的代码为 ERR_OSSL_X509_KEY_VALUES_MISMATCH。OpenSSL 1.1.1 使用的代码是 0B080074。
OpenSSL 3 — X509_R_KEY_VALUES_MISMATCH when loading a certificate with a private key (nginx, Node.js, Python, openssl s_server)
含义
TLS 服务器(或库)拿到的证书和私钥不属于同一对:证书中的公钥并不是这把私钥对应的公钥。OpenSSL 拒绝加载这一对文件,因此服务器无法启动,或者无法创建上下文。单看任何一个文件,都没有问题。
原因
证书是为更新(或更旧)的密钥签发的
常见续期时生成了新的密钥和 CSR,但配置仍指向旧的密钥文件;或者新证书被配上了去年的密钥。
证书包以中间证书开头,而不是叶子证书
常见服务器会把密钥与文件中的第一张证书比较。如果证书链文件的顺序是中间证书在前、叶子证书在后(或者根证书在最前面),即使叶子证书与密钥匹配,也会触发这个错误。
混用了来自不同主机或环境的文件
偶见在预发布环境和生产环境之间复制证书,或者在同一台服务器的多个名称之间复制证书,很容易把证书与另一台主机的密钥配在一起。
修复方法
- 1.
比较公钥
分别对从证书中提取的公钥和从私钥派生出的公钥计算哈希;哈希相同就说明它们属于同一对。这种方法同样适用于 RSA、EC 和 Ed25519 密钥。
bash # The two hashes must be identical openssl x509 -in server.pem -noout -pubkey | openssl sha256 openssl pkey -in server.key -pubout | openssl sha256 - 2.
把叶子证书放在证书包的最前面
列出证书包中各证书的主体;对应你主机名的叶子证书必须排在最前面,后面跟着中间证书。
bash # Servers match the key against the FIRST certificate of the file: make it the leaf openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout | grep subject= cat api.example.com.crt intermediate.crt > fullchain.pem - 3.
从多把密钥中找出匹配的那把
把证书公钥的哈希与每个候选密钥逐一比较;如果都不匹配,说明密钥已经丢失,必须用新密钥重新签发证书。
bash # Which of several keys belongs to the certificate? cert=$(openssl x509 -in server.pem -noout -pubkey | openssl sha256) for k in /etc/ssl/private/*.key; do [ "$(openssl pkey -in "$k" -pubout 2>/dev/null | openssl sha256)" = "$cert" ] && echo "match: $k" done