WebサイトからSSL証明書をダウンロードする方法


回答:


246

証明書をダウンロードするには、次のようにopensslに組み込まれているクライアントを使用する必要があります。

echo -n | openssl s_client -connect HOST:PORTNUMBER \
    | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/$SERVERNAME.cert

これにより、証明書がに保存され/tmp/$SERVERNAME.certます。

-showcertsチェーン内のすべての証明書をダウンロードする場合に使用できます。ただし、サーバー証明書をダウンロードするだけの場合は、指定する必要はありません-showcerts

echo -n 接続が解放されるように、サーバーに応答します

sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'証明書チェーンと接続の詳細に関する情報を削除します。これは、証明書を他のキーストアにインポートするための推奨形式です。


9
良い答えをしただけでなく、正確な説明もしてくれたことに感謝します。
marco.m 14年

-showcertsあまりにサーバー/葉の証明書を示して?そのスイッチが含まれている場合にのみ中間体を表示すると思った。
マイクB 14

答えが言ったs_clientように、サーバー証明書を常に表示します(サーバー証明書がある場合、つまりサーバーがhelloに応答し、匿名スイートを選択しません)。-showcerts示すすべての本命は、まず中間体および/またはルート証明書、サーバを受け取りました。
dave_thompson_085

4
ただし、これはプロキシが存在する場合は機能しません。
フレデリックノール

2
これは、SNI(単一のIPアドレス上の複数の証明書/ドメイン)を使用するサーバーでも機能しません。問題を回避するには、opensslのservernameパラメーターを指定します。openssls_client -connect HOST:PORTNUMBER -servername CN
verhage

60

答えを見つけました。Opensslが提供します。

openssl s_client -connect $ {REMHOST}:$ {REMPORT}


2
openssl x509 -text <<EOF cert-text EOF証明書の詳細も参照してください
-mpapis

2
sudo rm -f cert.pem && sudo echo -n | openssl s_client -connect localhost:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./cert.pem礼儀serverfault.com/questions/139728/...
pulkitsinghal

これは同じことを達成し、sedハックをスキップします。
phs

これは、1つの証明書をチェックするだけです。サービスが負荷分散されたサーバーのグループの一部であり、各サーバーが異なるルートCAによって署名された異なる証明書を持っている場合はどうでしょうか。言い換えれば、mitm攻撃により、このリクエストが実際のサイトに到達し、他のリクエストが自分のサーバーに送信される可能性があります。これを確認する方法はありますか?そして、ドメインが本当に持っているすべての証明書のリストを取得するには?
イェンスティマーマン14

@JensTimmerman 「つまり、mitm攻撃により、このリクエストが実際のサイトに到達してから、他のリクエストが自分のサーバーに送信される可能性があります。」man-in-the-middleがターゲットサーバーの有効な証明書を持っていない場合(またはクライアントが愚かでサーバー証明書をチェックしない場合)、それは不可能です。明らかに、サーバーが別の証明書を提供することがある場合、おそらく接続試行を繰り返して最終的にそれらすべてを取得することを望みます。
デビッドトンホーファー

22

GNUTLSのクライアントツールは、gnutls-cliまた、これは簡単に作ることができます。

gnutls-cli --print-cert www.example.com \
        < /dev/null \
        > www.example.com.certs

このプログラムは、サイトに対話型クライアントを提供するように設計されているため、対話/dev/null型セッションを終了するには、空の入力(この例ではfrom )を与える必要があります。


1
どのようにgnutlsが(システム全体で設定された)httpsプロキシを介して接続し、それが超過する証明書を印刷するのでしょうか?
フレデリックノール

9

@bignoseの回答に基づいて、以下はシェフのレシピなどによく適合する自己完結型のバージョンです。

sudo apt-get install gnutls-bin 
gnutls-cli --print-cert myserver.com </dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > myserver.crt
sudo cp myserver.crt /usr/local/share/ca-certificates/myserver.crt
sudo update-ca-certificates

6
true | openssl s_client -connect google.com:443 2>/dev/null | openssl x509

このopensslのモードはstdinを想定しているため、を介して提供しtrue |、これは-connectパラメーターで指定されたサーバーに接続します。2>/dev/null沈黙エラー(オプション)、/dev/stdinシェルパイプを入力ファイルとして使用するように指定して、出力全体をx509パーサーに渡すことができます。そして、それは出力の-----BEGIN CERTIFICATE-----to -----END CERTIFICATE-----部分だけを出力しs_clientます。> google.com.pemコマンドの最後に追加することで、ファイルにリダイレクトできます。


私が知る限り、これは証明書チェーンを検証するものではなく、エンドサーバーが提供するSSL IDのみを伝えることができます。


2
(1)これは6年前の回答を実際には改善しません(2)x509デフォルトでstdinを読み込むため-in /dev/stdin冗長です(3)s_clientサーバー証明書がローカルのトラストアンカー(ルート)に正しくチェーンされていることを確認しますが、有効期限はありませんこれを示す情報を抑制しました(4)失効を確認しません(5)サーバー証明書の名前を1.0.2でのみ確認し、デフォルトでは確認しません(ただし、証明書を見て簡単に確認できます)その後)
dave_thompson_085

@ dave_thompson_085、質問は証明書をダウンロードする方法ですが、チェーン情報を表示する方法ではありません。別の答えのsedよりもopenssl x509の方がずっと好きです。
Der_Meister

0

Exおよびプロセス置換を使用した代替構文:

ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq > file.crt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.