本文へスキップ
ecdsa.com
OpenSSL 3OpenSSL CLI

エラーメッセージ

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 はこの組み合わせの読み込みを拒否するため、サーバーが起動しなかったり、コンテキストを作成できなかったりします。どちらのファイルも、単体では何の問題もありません。

発生する理由

修正方法

  1. 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. 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. 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

関連するエラー

署名エラーデータベースをすべて見る