私は単一のサーバー1.1.1.1をいくつかのホストA.comとB.comに提供しています。 各ドメインにはそれぞれ独自の証明書があります。 urlでIPを使用するときのSNIを取得する方法
私はホストベースのURLを使用しています:URL url = new URL("https://B.com/23o8PS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
Certificate[] certificates = ((HttpsURLConnection) conn).getServerCertificates();
System.out.println(certificates.length + " " + certificates[0].toString());
私が正常にB.comの証明書を取得することができます。しかし、私は以下のように(ホストを示すために、Hostフィールドを追加することによって)IPベースのURLを使用する場合:
それは、サーバからデフォルトの証明書として返されるかのように、私はちょうどA.comの証明書を持ってURL url = new URL("https://1.1.1.1/23o8PS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Host", "B.com");
conn.connect();
Certificate[] certificates = ((HttpsURLConnection) conn).getServerCertificates();
System.out.println(certificates[0].toString());
。 HttpURLConnectionのHOST HEADERフィールドに従ってSNIを設定できないようです。
私はこの状況にどのように対処できますか?
URLにホスト名を使用します。 AFAIKでは、HTTPヘッダーが送信される前にSNIネゴシエーション全体が発生します。 – CommonsWare
@CommonsWare私はヘッダーが送信される前にそれが起こることを知っていますが、SNIは私がURLから来たと思ったサーバとネゴシエートする前にホスト情報を取得しなければなりません。ですから、ヘッダーフィールドの優先順位が高いので、URLの代わりにヘッダーフィールドからホストを取得できるかどうかは疑問です。そして、それはうまくいかないようです。だから私はIPベースのリクエストでそれを行う方法はありませんか? – Ryan
@ Ryan:HttpUrlConnectionの抽象度レベルでこれを処理できるかどうかは疑問です。ソケットのレベルで行うことができます。http://developer.android.com/reference/android/net/SSLCertificateSocketFactory.html#setHostname(java.net.Socket、java.lang.String)を参照してください。 –