次のようなコードがあります。
// configure the SSLContext with a TrustManager
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0],
new TrustManager[] {new DefaultTrustManager()},
new SecureRandom());
SSLContext.setDefault(ctx);
URL url = new URL(urlString); // https://abc.myhost.com
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
System.out.println("verify:" + arg0);
return true;
}
});
System.out.println("HTTP status: " + conn.getResponseCode());
Certificate[] certs = conn.getServerCertificates();
int c=0;
for (Certificate cert : certs){
String t = cert.getType();
System.out.println(String.format("\ncert[%d]: %s",c,t));
c++;
if (pi.verbose) {
System.out.println(cert);
}
else if (cert instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate) cert;
System.out.println(x509cert.getSubjectDN().getName());
}
}
Java 6 で特定の Web サイトに対してこのコードを実行すると、Java 7 で取得した証明書とは異なる証明書が取得されます。ホスト名が abc.myhost.com であるとします。
Java6で私は得る:
cert[0]: X.509
CN=example.com,OU=Secure Link SSL Pro,O=Company Name Here,
STREET=2001 Space Odyssey Dr,L=Weirton,ST=Wv,2.5.4.17=#13053330303034,C=US
Java7 では次のようになります。
cert[0]: X.509
CN=abc.myhost.com,OU=Secure Link SSL Pro,O=Company Name Here,
STREET=2001 Space Odyssey Dr,L=Weirton,ST=Wv,2.5.4.17=#13053330303034,C=US
有効な日付を出力すると、それらも異なります。シリアルナンバーもそのまま。これらは異なる証明書です。
Java 7 では正しく見えます。Java 6 では、ホスト名と CN の間に不一致があります。証明書が間違っているようです。
このサーバーがプロキシの背後にある可能性は十分にあります。そのサーバーの所有者 (私が取り組んでいるプロジェクトのパートナー) が最近証明書を変更した可能性もあります。2 つの証明書が存在する可能性があります。1 つはプロキシ サーバー上にあり、もう 1 つはプロキシ サーバーの背後にあるサーバーにあります。私は彼らにこれを調べてもらいました。
私が持っている質問は、Java7 で Java6 と同じ結果が得られないのはなぜですか? Java は で何かを変更しましたHttpsURLConnection.getServerCertificates()
か?
好奇心旺盛な人にとっては、これは単なる診断作業です。実際のエラーは次のとおりです。
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException:
No subject alternative DNS name matching abc.myhost.com found.
この場合の問題は通常、証明書のホスト名と CN の間の不一致です。私は意見の不一致を確認しましたが、Java 6 でのみです。Java6 と Java7 が異なる理由を理解したいと思います。
EDIT : Python 2.7.1 スクリプトは、Java6 と同じ証明書を返します。
SSLConnection.get_peer_cert()
CN が一致しない証明書を表示します。