証明書Exception:ssl.someurl.deが見つかった名前はありません

StackOverflow https://stackoverflow.com/questions/3093112

  •  29-09-2019
  •  | 
  •  

質問

Javaを使用して、SSLを介してサーバーの1つに接続しようとしています。私はここでたくさんのオプションを試しました私の最善の試みです:

推奨スクリプトを使用してjssecacertsを生成します。 http://blogs.oracle.com/andreas/resource/installcert.javaコマンドを使用:Java installCert SSL.Someurl.de ChangeIT

この後、私はもう一度コマンドをしました:

Loading KeyStore jssecacerts...
Opening connection to ssl.someUrl.de:443...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   Issuer  EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Hernd
on, ST=Virginia, C=US
   sha1    f1 0d 2c 54 05 e1 32 19 a0 52 5e e1 81 6c a3 a5 83 0d dd 67
   md5     f0 b3 be 5e 5f 6e 90 d1 bc 57 7a b2 81 ce 7d 3d

Enter certificate to add to trusted keystore or 'q' to quit: [1]

ファイルをデフォルトのディレクトリにコピーし、Java TrustStoreに証明書をロードしました

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jre6\\lib\\security\\jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");

それから私は接続しようとします

URL url = new URL("https://ssl.someUrl.de/");
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

そして、3行目でエラーが発生します:( SSL.someurl.deが見つかった名前はありません)

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching ssl.someUrl.de found

これはデフォルトのPlesk証明書の原因ですか、それとも他の何かが間違っていますか?

セットアップ:JRE 6.20、NetBeans 6.8、Windows7 64bit

役に立ちましたか?

解決

接続しようとしているサーバーの証明書がそのホスト名と一致しないようです。

HTTPSクライアントがサーバーに接続すると、証明書のホスト名がサーバーのホスト名と一致することを確認します。証明書を信頼するだけでは十分ではなく、話したいサーバーも一致する必要があります。 (類推として、たとえパスポートが合法であると信頼していても、あなたが正当であると信頼するパスポートだけでなく、あなたが話したい人のためのものであることを確認する必要があります。)

HTTPでは、これを確認することによって行われます。

  • 証明書には、ホスト名に一致するDNSサブジェクトの代替名(これは標準拡張機能)エントリが含まれています。

  • それに失敗すると、被写体の最後のCNが著名な名前(これが必要な場合はメイン名です)はホスト名と一致します。 (RFC2818を参照してください。)

証明書を持っていない場合は、主題の代替名が何であるかを知るのは困難です(ただし、ブラウザに接続してそのコンテンツをより詳細に確認すると、それを見ることができるはずです。)

EMAILADDRESS=info@plesk.com, CN=plesk, OU=Plesk, O=Parallels, L=Herndon, ST=Virginia, C=US

(したがって、cn = pleskの代わりにcn = ssl.someurl.deである必要があります。dns:ssl.someurl.deに件名の代替名がない場合は、すでにそうではないと思います。)

ホスト名の検証を使用してバイパスできる場合があります httpsurlconnection.sethostnameverifier(..). 。検証を裏打ちするカスタムホストネームヴェリファイアを書くのはそれほど難しくないはずですが、証明書がここに関係している場合にのみ行うことをお勧めします。 SSLSession引数とそのgetPeercertificates()メソッドを使用してそれを取得できるはずです。

(さらに、とにかくデフォルト値を使用しているため、javax.net.ssl。*プロパティを設定する必要はありません。)

または、接続しているサーバーとその証明書を制御できる場合は、上記の命名ルールに一致する証明書を作成できます(CNで十分である必要がありますが、対象の代替名は改善です)。自己署名証明書があなたが名前を付けるのに十分である場合、その共通名(CN)があなたが話しようとしているホスト名であることを確認してください(完全なURL、ホスト名のみ)。

他のヒント

Java 8では、次のコードでサーバー名のチェックをスキップできます。

HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -> true);

ただし、これは開発でのみ使用する必要があります!

fixuntrustcertificate()メソッドを作成したため、信頼できるCASにないドメインを扱っている場合、リクエスト前にメソッドを呼び出すことができます。このコードはJava1.4の後に機能します。この方法は、すべてのホストに適用されます。

public void fixUntrustCertificate() throws KeyManagementException, NoSuchAlgorithmException{


        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }

            }
        };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // set the  allTrusting verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}

ここで良い解決策を見つけました: http://www.mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/

しかし、私の問題は少し違っていて、それを異なって解決しました。

Webサービスはリモートホストにありました。例えば: https://some.remote.host/mywebservice?wsdl

ただし、クライアントの場合はIPでのみ使用できましたが、domain:some.remote.host(cn = some.remote.host)の証明書が作成されました。また、このドメインはDNSで提示されていないため、IPによって解決することはできません)。

同じ問題が表示されました。IPを使用してSSLでWebサービスに接続すると、証明書cn = some.remote.hostで到達することはできません。 。

このホスト名を /etc /hostsファイルでIPと一致させることで解決しました。問題は修正されました。

ただし、WebサービスがLocalHost App Serverでホストされている場合は、Mkyongの記事に記載されているように解決する必要があると考えています。

サーバー名は、証明書を作成する際に提供する最初の/姓と同じでなければなりません

Kafkaエラーを探している場合、これは1.xから2.xまでのKafkaのバージョンのアップグレードがあるためかもしれません。

javax.net.ssl.ssslhandshakeexception:一般的なsslengineの問題... javax.net.ssl.ssl.shakeexception:一般的なsslengineの問題... java.security.cert.certificateexception:名前はありません*名はありません***

また

プロデューサーclientidid = producer -1]ノード-2への接続 - 認証の失敗:SSLハンドシェイクが失敗しました

ssl.endpoint.identification.algorithmのデフォルト値はHTTPSに変更され、ホスト名検証を実行します(そうでなければ、中間攻撃が可能です)。 ssl.endpoint.identification.algorithmを空の文字列に設定して、以前の動作を復元します。 Apache Kafka 2.0.0の注目すべき変更

解決策:sslconfigs.ssl_endpoint_identification_algorithm_config、 ""

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top