Java sun.security.validator.validator异常

Java sun.security.validator.validator异常,java,https,Java,Https,我有一个桌面应用程序。 任务是添加加载文件的https协议。 有一种方法 static public void test(){ try { SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new TrustManager[] {new X509TrustManager(){ @Override

我有一个桌面应用程序。 任务是添加加载文件的https协议。 有一种方法

 static public void test(){
    try {
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], 
            new TrustManager[] {new X509TrustManager(){
                @Override public void checkClientTrusted(
                     X509Certificate[] arg0, String arg1) 
                throws CertificateException {}

                @Override public void checkServerTrusted(
                     X509Certificate[] arg0, String arg1) 
                throws CertificateException {}

                @Override public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }}}, new SecureRandom());
        SSLContext.setDefault(ctx);

        URL url = null;

        url = new URL("https://tlauncher.org/repo/test" +
                      "/ConfigPreMasterSALF-2.18.json");

        HttpsURLConnection conn = (HttpsURLConnectio) url.openConnection();
        conn.setHostnameVerifier(new HostnameVerifier() {
           @Override public boolean verify(String arg0, SSLSession arg1) {
              return true;
           }
        });
        BufferedReader reader = new BufferedReader(new InputStreamReader(
            conn.getInputStream(),"utf8"));

        StringBuilder response = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            response.append(line);
        }
        reader.close();
        System.out.println(response.toString());
        conn.disconnect();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
服务器具有签名服务。
如何改进或实现使用服务器的另一种方式?

从GetAcceptedAssuers返回null会告诉客户端代码中的验证方法不信任HTTPS服务器持有的任何证书。这样,客户端将永远不会信任服务器,并且无法建立连接。要使其正常工作,您应该返回certificate Authority(CA)证书,即权威机构用来签署服务器证书的证书。让我们把CA证书称为信任的根。不管怎么说,这是你在这里做的大量工作,而Java有预先构建的工具,你可以在网上找到很多例子

您正在使用的库称为JCA Java加密体系结构,它可以存储此类证书以供将来使用。使用JCA的keytool将信任根导入密钥存储,并在打开到服务器的安全连接之前激活该密钥存储

JCA如何支持SSL/TLS,而SSL/TLS反过来又用于HTTPS中的“S”,可以在这里找到:它还更详细地介绍了KeyManager、TrustManager和密钥库工具

不管怎样,我已经尝试了你的代码指向的URL,它在Firefox浏览器和Java中都运行得非常好。它带有来自COMODO CA的有效SSL证书。如果这是您试图获取的真实URL,您可以完全忘记JCA,跳过设置SSLContext并在没有验证器的情况下打开连接

URL url = new URL("https://tlauncher.org/repo/test/ConfigPreMasterSALF-2.18.json");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(
        conn.getInputStream(),"utf8"));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
    response.append(line);
}
reader.close();
System.out.println(response.toString());

以下是您当前版本的一些问题:

  • 您的SSLContext配置错误。最好不要设置SSLContext1。这将导致SSL堆栈使用默认堆栈,该堆栈将使用JRE密钥库中的受信任根
  • 您的HostnameVerifier将接受任何主机名,这使得添加一个主机名毫无意义。(这就是默认验证器所做的。)
  • 如果要使用HostnameVerifier,必须在建立连接之前设置它。方法是使用静态
    setDefaultHostnameVerifier
    方法
  • 代码可能会泄漏套接字文件描述符。读取器应在
    finally
    块中关闭

  • 1-如果需要覆盖密钥库中的内容或执行与正常行为不同的其他操作,可以使用SSLContext。例如,您可能希望关闭某个已知可信服务器上的验证,该服务器的证书已过期。或者您可能希望不信任给定的根CA