8

クライアント ライブラリ (現在は Python、Ruby、PHP、Java、および .NET) が正しく構成され、SSL 証明書が無効な場合に適切に失敗することを確認したいと考えています。Shmatikov の論文The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Softwareは、SSL 検証がいかに混乱を招くかを明らかにしているので、起こりうる失敗を徹底的にテストしたいと思います。

調査によると、次の場合、証明書は無効です。

  • 有効化日前に使用されている
  • 有効期限を過ぎてから利用する
  • 取り消されました
  • 証明書のホスト名がサイトのホスト名と一致しません
  • 証明書チェーンに信頼できる認証局が含まれていません

理想的には、無効なケースごとに 1 つのテスト ケースがあると思います。そのために、私は現在、経由でHTTPアクセスしたサイトをテストしていますHTTPS。これは、次のようなテストで確認できる失敗につながります。

self.assertRaises(SSLHandshakeError, lambda: api.call_to_unmatched_hostname())

これは不完全で (1 つのケースのみをカバーしています)、間違っている可能性があるため...

ブラウザー以外のソフトウェアが SSL 証明書を適切に検証することをどのようにテストできますか?

4

2 に答える 2

6

まず、SSL 証明書のコレクションが必要です。それぞれに 1 つの問題があります。これらは、openssl コマンド ライン ツールを使用して生成できます。もちろん、信頼されたルート CA で署名することはできません。独自の CA を使用する必要があります。これを正しく検証するには、CA 証明書をクライアント ライブラリにインストールする必要があります。たとえば、コントロール パネルを使用して、Java でこれを行うことができます。

証明書を取得したら、「openssl s_server」ツールを使用して、各証明書を使用して SSL ソケットを提供できます。各ポートに 1 つの証明書を配置することをお勧めします。

クライアント ライブラリを使用してポートに接続し、正しいエラー メッセージが表示されることを確認する必要があります。

Python はデフォルトで証明書の検証を行わないことを知っています (httplib.HTTPSConnection のマニュアルを参照してください)。ただし、m2crypto は検証を行います。Java はデフォルトで検証を行います。他の言語についてはわかりません。

テストできるその他のケース: 1) ワイルドカードのホスト名。2) 証明書チェーン。古いブラウザには、ルートによって署名された証明書 A がある場合、A が B に署名でき、B が有効に見えるというバグがあったことを知っています。SSL は、証明書にフラグを設定することでこれを停止することになっていますが、A には「署名可能」フラグがありません。ただし、これは一部の古いブラウザでは検証されていません。

幸運を!私はあなたがどのようにうまくやっていくのか興味があります。

ポール

于 2013-06-24T17:27:34.363 に答える
5
  • 証明書のホスト名がサイトのホスト名と一致しません

    これはおそらくチェックするのが最も簡単で、失敗 (失敗すること) は確かに何かが間違っていることを示す良い兆候です。よく知られているサービスのほとんどの証明書は、IP アドレスではなく、ホスト名のみを識別に使用します。を求める代わりに、(たとえば) を求めて動作する場合は、何か問題がありますhttps://www.google.com/https://173.194.67.99/

他のものについては、独自のテスト CA を生成することができます。

  • 証明書チェーンに信頼できる認証局が含まれていません

    テスト CA (または自己署名証明書) を使用してテスト証明書を生成できますが、検証には既定のシステム CA リストを使用します。テスト クライアントはその証明書の検証に失敗するはずです。

  • 有効期限前に使用された場合、有効期限後に使用された場合

    現在の日付を無効にする notBefore/notAfter 日付を使用して、テスト CA を使用してテスト証明書を生成できます。次に、テスト CA を検証用の信頼できる CA として使用します。テスト クライアントは、日付が原因で証明書の検証に失敗するはずです。

  • 取り消されました

    失効の公開方法にもよりますが、これはおそらく最も設定が難しいものです。ここでも、独自のテスト CA を使用して、すぐに取り消したテスト証明書をいくつか生成します。一部のツールは、一連の信頼できる CA の隣にある一連の CRL ファイルを使用して構成することを想定しています。これには、テスト自体のセットアップが必要ですが、オンライン セットアップはほとんど必要ありません。これがおそらく最も簡単です。CRL 配布ポイントや OCSP などを使用して、ローカルのオンライン失効リポジトリを設定することもできます。

PKI テストは、より一般的にはより複雑になる可能性があります。完全なテスト スイートを作成するには、仕様 (RFC 5280) を十分に理解している必要があります。実際、すべての中間証明書の日付と、チェーン内の各証明書のさまざまな属性 (鍵の使用法、基本的な制約など) を確認する必要がある場合があります。

一般に、クライアント ライブラリでは、検証プロセスが 2 つの操作に分けられます。証明書が信頼されていることの検証 (PKI 部分) と、証明書が接続先のエンティティに対して発行されたことの検証 (ホスト名検証部分) です。これは確かに、これらが異なるドキュメント (それぞれ RFC 3280/5280 および RFC 2818/6125) で指定されているという事実によるものです。

実用的な観点から、SSL ライブラリを使用する際に確認すべき最初の 2 つのポイントは次のとおりです。

  • 既知のホストに接続しているが、証明書が有効でない別の識別子 (ホストではなくその IP アドレスなど) を使用するとどうなりますか?
  • デフォルトのトラステッド アンカー セット (自己署名証明書や独自の CA など) では検証できないことがわかっている証明書に接続するとどうなりますか。

どちらの場合も、接続/検証の失敗が発生するはずです。すべてが機能する場合、完全な PKI テスト スイート (特定の専門知識が必要) を実装するまでは、SSL ライブラリのドキュメントをチェックして、これらの検証を有効にする方法を確認する必要がある場合がよくあります。

バグは別として、このホワイト ペーパーで言及されている問題のかなりの数は、ライブラリの実装によっては、自分が何をしているかを知るのはユーザー次第であると仮定しているという事実によるものですが、ほとんどのユーザーは仮定をしているようです。ライブラリがデフォルトで正しいことをしていたこと。(実際、ライブラリがデフォルトで正しいことを行っている場合でも、アプリケーションが安全でなくなったとしても、エラー メッセージを取り除きたいだけのプログラマーは少なくありません。)ほとんどの場合、検証機能がオンになっていることを確認するだけで十分です。

いくつかの既存の実装のステータスについては、次のとおりです。

  • Python: Python 2.x と Python 3.x の間で変更がありました。sslPython 3.2のモジュールにはmatch_hostname、Python 2.7 にはないメソッドがあります。urllib.request.urlopenPython 3.2 には CA ファイルを設定するオプションもありますが、これは Python 2.7 に相当するものにはありません。(とは言っても、設定しないと検証が行われません。ホスト名の検証についてはよくわかりません。)

  • Java: の PKI とホスト名の両方に対して検証がデフォルトでオンになっていますが、Java 7 を使用していて(たとえば) Java 7 を使用して構成していない限り、直接HttpsUrlConnection使用する場合はホスト名に対してはオンになっていません。SSLSocketSSLParameterssetEndpointIdentificationAlgorithm("HTTPS")

  • PHP: 私の知る限り、fopen("https://.../")検証はまったく実行されません。

于 2013-06-24T18:22:28.063 に答える