openssl verifyを使用して証明書チェーンを確認します


128

私は次のコンポーネントで独自の証明書チェーンを構築しています:

Root Certificate - Intermediate Certificate - User Certificate

ルート証明書は自己署名証明書、中間証明書はルートによって署名され、ユーザーは中間証明書によって署名されます。

次に、ユーザー証明書にルート証明書によるアンカーがあるかどうかを確認します。

openssl verify -verbose -CAfile RootCert.pem Intermediate.pem

検証は問題ありません。次のステップでは、ユーザー証明書を

openssl verify -verbose -CAfile Intermediate.pem UserCert.pem

そして検証は

error 20 at 0 depth lookup:unable to get local issuer certificate

なにが問題ですか?

回答:


164

verifyドキュメントから:

独自の発行者である証明書が見つかった場合、その証明書はルートCAであると見なされます。

つまり、ルートCAは検証を機能させるために自己署名する必要があります。これが、2番目のコマンドが機能しなかった理由です。代わりにこれを試してください:

openssl verify -CAfile RootCert.pem -untrusted Intermediate.pem UserCert.pem

1つのコマンドでチェーン全体を確認します。


2
私はアップ投票私は最近、これをしなければならなかったと記載されていることにより、異なるオプションを試した後、この答えをman verify、私はことを発見し-untrustedたパラメータは、中間証明書を指定するときに使用する正しいものです。
Anthony Geoghegan 2015

2つ目の答えは、stackoverflow.com / a / 31205833/173062の方が正確だと思います。証明書のチェーンを-CAfileパラメータに渡します。
Glenjamin

2
-untrusted証明書チェーンが完全に有効かどうかはチェックしません。-CAfile他の質問が示唆するように、中間とルートの両方をコマンドに渡すことを検討してください。
Envek 2016年

2
次のことが起こる可能性がある場合に使用することはIntermediate.pemため-untrusted:mail.python.org/pipermail/cryptography-dev/2016-August/...
グレッグSmethells

2
それはOPが要求したものではありませんが、自己署名されていないチェーンを検証したい場合は、独自のチェーンの代わりにシステム/ブラウザCAファイルを使用してください。たとえば、自作のopensslを使用するOS Xの場合:openssl verify -CAfile /usr/local/etc/openssl/cert.pem -untrusted Intermediate.pem UserCert.pem
Greg Dubicki 2017年

50

これは、数少ない合法的な仕事の1つですcat

openssl verify -verbose -CAfile <(cat Intermediate.pem RootCert.pem) UserCert.pem

更新:

Greg Smethellsがコメントで指摘しているように、このコマンドは暗黙的にIntermediate.pemを信頼します。ポストGregのリファレンスの最初の部分を読むことをお勧めします(2番目の部分は特にpyOpenSSLに関するものであり、この質問には関係ありません)。

投稿が消えた場合に備えて、重要な段落を引用します。

残念ながら、実際にルート/自己署名された「中間」証明書は、 上記の推奨コマンドを使用する場合、信頼できるCAとして扱われます。

$ openssl verify -CAfile <(cat geotrust_global_ca.pem rogue_ca.pem)fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem:OK

opensslは、ルート証明書が検出されるとすぐにチェーンの検証を停止するようです。これは、自己署名されている場合はIntermediate.pemの場合もあります。その場合、RootCert.pemは考慮されません。したがって、上記のコマンドに依存する前に、Intermediate.pemが信頼できるソースからのものであることを確認してください。


これは実際にルート証明書に対して中間証明書を検証しますか?
augurar

します。正しいとわかっているチェーンを使用してコマンドを再実行しました(雇用者の生産トラフィックに対応します)。次に、関連のない別のルート証明書を使用します。記録の要旨を参照してください。
ピーター

8
警告:DO NOT Intermediate.pemはすべて信頼できないでいる場合は、これを使用しています。詳細情報についてはこちらをお読みください。mail.python.org/pipermail/cryptography-dev/2016-August/...
グレッグSmethells

1
指摘してくれてありがとう、グレッグ。答えたところ、発行者のホームページからルートと中間体の両方をダウンロードしたので、思いもよらなかった。中間体がこのコマンドで暗黙的に信頼されていることを明確にするために、回答を更新しました。
Peter

1
@ somenickname、Tonyのコメントを参照してください。とにかく-untrustedオプションをお勧めします。さらにサポートが必要な場合は、ご自身で質問することをお勧めします。コメントは、問題をデバッグするのに適切な場所ではありません。
Peter

17

問題は、それopenssl -verifyが仕事をしないということです。

Priyadiが述べたようにopenssl -verify最初の自己署名証明書で停止するため、中間証明書が自己署名されることが多いため、実際にはチェーンを検証しません。

本番のWebサービスに証明書ファイルをインストールする前に、証明書ファイルが正しいことを101%確認したいと思います。ここのレシピは、まさにこの飛行前チェックを実行します。

Peterの答えが正しいことに注意しください。ただし、の出力はopenssl -verify、すべてが実際に機能するという手がかりにはなりません。はい、問題が見つかるかもしれませんが、すべてではありません。

Apacheにインストールする前に証明書チェーンを検証するジョブを実行するスクリプトを次に示します。おそらくこれは、より神秘的なOpenSSLマジックのいくつかで強化できるかもしれませんが、私はOpenSSLの第一人者ではなく、以下の作業を行っています。

#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL.  USE AT OWN RISK, ABSOLUTELY NO WARRANTY. 
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)

OOPS() { echo "OOPS: $*" >&2; exit 23; }

PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0

serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "$@" -www &
PID=$!
sleep .5    # give it time to startup
}

check()
{
while read -r line
do
    case "$line" in
    'Verify return code: 0 (ok)')   return 0;;
    'Verify return code: '*)    return 1;;
#   *)  echo "::: $line :::";;
    esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}

ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"

for a in "$KEY" "$CRT" "$BND"
do
    [ -s "$a" ] || OOPS "missing $a"
done

serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick

echo
case $ret in
0)  echo "EVERYTHING OK"
    echo "SSLCertificateKeyFile $KEY"
    echo "SSLCertificateFile    $CRT"
    echo "SSLCACertificateFile  $BND"
    ;;
*)  echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac

exit $ret

後の出力EVERYTHING OKはApacheの設定であることに注意してください。これを使用している人、NginXまたはhaproxy通常はこれを完全に読んで理解できるためです;)

これのGitHub Gistがあり、いくつかの更新がある可能性があります

このスクリプトの前提条件:

  • /etc/ssl/certsUbuntuなどの通常どおり、信頼されたCAルートデータがあります。
  • DIR3つのファイルを格納するディレクトリを作成します。
    • DIR/certificate.crt 証明書が含まれています
    • DIR/certificate.key ウェブサービスの秘密鍵が含まれています(パスフレーズなし)
    • DIR/certificate.bundleこれにはCAバンドルが含まれています。バンドルの作成方法については、以下を参照してください。
  • スクリプトを実行します./check DIR/certificate(これは、スクリプトがcheck現在のディレクトリで名前が付けられていることを前提としています)。
  • スクリプトが出力することはほとんどありませんCA-Bundle is not needed。これは、あなた(読み取り/etc/ssl/certs/:)がすでに署名証明書を信頼していることを意味します。しかし、これはWWWではほとんどありません。
  • このテストでは、ワークステーションでポート4433を使用しないでください。また、安全な環境でのみこれを実行することをお勧めします。これは、ポート4433がまもなく公開され、悪意のある環境で外部接続が発生する可能性があるためです。

certificate.bundleファイルを作成するには?

WWWでは、信頼チェーンは通常次のようになります。

  • からの信頼できる証明書 /etc/ssl/certs
  • 不明な中間証明書、おそらく別のCAによって相互署名されています
  • 証明書(certificate.crt

これで、評価は下から上に行われます。つまり、最初に証明書が読み取られ、次に不明な中間証明書が必要です。次に、相互署名証明書がおそらく/etc/ssl/certs参照され、適切な信頼できる証明書を見つけるために参照されます。

caバンドルは、正確に正しい処理順序で作成する必要があります。つまり、最初に必要な証明書(証明書に署名する中間証明書)がバンドルの最初に来ます。次に、相互署名証明書が必要です。

通常、CA(証明書に署名した機関)は、そのような適切なca-bundle-fileをすでに提供しています。そうでない場合は、必要なすべての中間証明書とcatそれらを1つのファイルにまとめる必要があります(UNIXの場合)。Windowsでは、テキストエディター(などnotepad.exe)を開いて、証明書をファイルに貼り付けるだけです。

別のものがあります。ファイルはPEM形式である必要があります。一部のCAはDER(バイナリ)形式を発行します。PEMは簡単に見つけられます。ASCIIで読み取り可能です。何かをPEMに変換する方法の詳細については、「。crtを.pemに変換する方法」を参照し、黄色いレンガの道をたどってください。

例:

あなたが持っている:

  • intermediate2.crt 署名した中間証明書 certificate.crt
  • intermediate1.crt 歌った別の中間証明書 intermediate2.crt
  • crossigned.crt これは、署名された別のCAからの相互署名証明書です intermediate1.crt
  • crossintermediate.crtこれは、署名した他のCAからの別の中間体crossigned.crtです(おそらく、そのようなことは決してないでしょう)。

次に、適切なものcatは次のようになります。

cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle

そして、どのファイルが必要であるか、どのシーケンスで必要かをどのようにして見つけることができますか?

ええと、checkすべてが問題ないと言うまで、実験してください。それは謎を解くコンピューターパズルゲームのようなものです。すべて。シングル。時間。プロでも。しかし、これを行う必要があるたびに良くなります。ですから、あなたはそのような苦痛を伴うだけで決定的に一人ではありません。SSLですよね。SSLはおそらく、30年以上にわたる専門的なシステム管理で見た中で最悪の設計の1つです。過去30年間で暗号化が主流にならない理由を知りましたか?それが理由です。'言っ途切れる。


反対投票者へ:私の回答のどこが悪いのか説明してください。ありがとう。
ティノ

2
私は反対投票者の一人です。反対投票のきっかけは次のとおりです。「必要なファイルと不要なファイルを、どの順序でどのようにして見つけることができますか?さて、チェックですべてがOKと表示されるまで実験してください」。SSLは特別なケースではないと思います。このような問題には確定的な解決策が必要です。
ychaouche 2016

2
@ychaoucheありがとう!あなたのように私は決定論的なものが好きです。問題は、「何が問題なのか」と「openssl verify」でそれを行う方法です。私たちがスタックオーバーフローにいるので、私はそれを説明し、続いてプログラムによる(したがって決定論的な)はい/いいえの答えを示しました。これを使用して、本番環境にインストールする前に新しいバンドルのチェックを自動化することもできます。これは質問に完全に答えます。あなたが嫌い​​なのは、「適切なバンドルを作成するにはどうすればよいですか?」に関する欲求不満について私が言ったことです。私はそのための短い決定論的な答えはあり得ないと思うので、これに答えることはここでの文脈ではトピック外です。
Tino、

6
「プリヤディが述べたように、openssl -verifyは最初の自己署名証明書で停止するため、中間証明書が自己署名されていることが多いため、実際にはチェーンを検証しません。」明らかに、中間証明書は自己署名されることはありません(それらがルート証明書である場合)。検証の全体的なポイントは、信頼できるルート証明書までのチェーンにすべての証明書が含まれていることを確認することです。これはまさにopenssl verifyが行うことです。ただし、opensslはその信頼ポリシーではかなり保守的である傾向があります...
Timo

4
「多くの場合、中間証明書は自己署名されています」。これは誤りであり、このような用語の混乱により、初心者は、正しい方法で説明すると実際にはかなり単純なトピックを理解することが難しくなります。RFC 5280から:「[...] CA証明書は、相互認証、自己発行の証明書、自己署名証明書の3つのクラスにさらに分類される場合があります。相互認証は、発行者とサブジェクトが異なるエンティティであるCA証明書です。クロス証明書は、2つのCA間の信頼関係を記述します。[...] "
Jan-Philip Gehrcke博士2017

8

私はletsencrypt証明書の検証を行わなければならなかったので、次のようにしました。

  1. ルート証明書と中間証明書をletsencrypt信頼チェーンからダウンロードします
  2. 次のコマンドを発行します。

    $ openssl verify -CAfile letsencrypt-root-cert/isrgrootx1.pem.txt -untrusted letsencrypt-intermediate-cert/letsencryptauthorityx3.pem.txt /etc/letsencrypt/live/sitename.tld/cert.pem 
    /etc/letsencrypt/live/sitename.tld/cert.pem: OK
    

1
さて、ジョンは私があなたに感謝したと言ったことを好きではなかったようです。私は「ありがとう」を強く主張しているので、ここに削除されたテキストがあります。Priyadiに感謝します。あなたの解決策がこのコマンドを見つけるのに役立ちました。必ず彼の解決策に賛成票を投じてください。
マイケル

5

SSL証明書に関する事前の知識がまったくなく、まったく同じ問題について1日中過ごした後、CERTivity Keystores Managerをダウンロードして自分のキーストアをインポートし、証明書チェーンを明確に視覚化しました。

スクリーンショット:

ここに画像の説明を入力してください


1
使用方法に関する質問に答えようとしないでくださいopenssl verify
binki

はい。ただし、opensslコマンドラインツールの不可解な情報を理解していない場合、この種類のツールを使用すると、その種のことを視覚化することができます:)これが私の賛成投票です。オンラインで同様のことが行われる場合もあります。
David天宇Wong

2

あなただけのことを検証したい場合は、発行者のをUserCert.pem 実際には Intermediate.pem、次の(例の用途を:行いますOpenSSL 1.1.1):

openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pem

あなたが得るでしょう:

UserCert.pem: OK

または

UserCert.pem: verification failed

openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pemPython 3.7に相当するコマンドはありますか?
ボゴタ

-5

opensslで証明書チェーンを簡単に確認できます。フルチェーンにはCA証明書が含まれるため、CAと証明書自体の詳細が表示されます。

openssl x509 -in fullchain.pem -text -noout


4
1)これはまったく説明のないことです。2)これは、コンテキストなしで質問者が尋ねなかった質問への回答です。
Shadur、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.