私はJavaでクライアントを作成しています(デスクトップJREとAndroidの両方で動作する必要があります)。TLSを介して実行される独自のプロトコル(私の会社に固有)用です。Java で TLS クライアントを作成する最善の方法を見つけようとしています。特に、ホスト名の検証が適切に行われるようにします。(編集:つまり、中間者攻撃を避けるために、ホスト名が X.509 証明書と一致することを確認することを意味します。)
JSSE は TLS クライアントを作成するための明白な API ですが、SSLSocketFactory API を使用している場合、JSSE はホスト名を検証しないことに気付きました (および実験から) 。(私のプロトコルは HTTPS ではないため、これを使用する必要があります。)
そのため、JSSE を使用する場合、ホスト名の検証を自分で行う必要があるようです。そして、そのコードをゼロから作成するのではなく (ほぼ間違いなく間違いを犯すため)、動作する既存のコードを「借りる」必要があるようです。したがって、私が見つけた最も可能性の高い候補は、Apache HttpComponents ライブラリを使用し (皮肉なことに、私は実際に HTTP を行っていないため) 、標準の javax の代わりに org.apache.http.conn.ssl.SSLSocketFactory クラスを使用することです。 .net.ssl.SSLSocketFactory クラス。
私の質問は次のとおりです。これは合理的な行動方針ですか?それとも、私は物事を完全に誤解し、深いところから抜け出し、実際には、HttpComponents のようなサードパーティのライブラリを引き込まずに、JSSE でホスト名の検証を取得するはるかに簡単な方法がありますか?
また、TLS 用の非 JSSE API を備えた BouncyCastle も調べましたが、証明書チェーンの検証も行わず、ホスト名の検証も行わないという点で、さらに制限されているようです。 -スターター。
編集:この質問は Java 7 について回答されていますが、Java 6 と Android の「ベスト プラクティス」が何であるかについてはまだ興味があります。(特に、アプリケーションで Android をサポートする必要があります。)
再度編集:「Apache HttpComponents から借用する」という私の提案をより具体的にするために、Apache HttpComponents から抽出された HostnameVerifier 実装 (最も顕著なのは StrictHostnameVerifier と BrowserCompatHostnameVerifier) を含む小さなライブラリを作成しました。(必要なのはベリファイアだけであり、当初考えていた Apache の SSLSocketFactory は必要ないことに気付きました。) 自分のデバイスに任せる場合、これが私が使用するソリューションです。しかし、まず、私がすべきではない理由はありますかこのようにしますか?(私の目標は、https と同じ方法でホスト名の検証を行うことであると仮定します。それ自体は議論の余地があり、暗号化リストのスレッドで議論されていることを理解していますが、今のところ、HTTPS のようなホスト名に固執しています私は HTTPS を行っていませんが、検証を行っています。)
私のソリューションに「問題」が何もないと仮定すると、私の質問は次のとおりです。Java 6、Java 7、および Android 間で移植性を維持しながら、それを行うための「より良い」方法はありますか? (「より良い」とは、より慣用的で、すでに広く使用されていること、および/または必要な外部コードが少ないことを意味します。)