java SSLHandshakeException 当我尝试从我的 web 应用程序在 tomcat 服务器中发送 get 或 post https 请求时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12190282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:57:12  来源:igfitidea点击:

SSLHandshakeException when i try to send a get or post https request from my webapp in tomcat server

javasecuritysslhttpsssl-certificate

提问by Ruwan Dissanayaka

Follwing exception is thrown when send https request from my webapp in tomcat server

从我的 webapp 在 tomcat 服务器中发送 https 请求时抛出以下异常

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径

here is my servelet

这是我的小服务器

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package LBS;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLConnection;
import javax.net.ssl.HttpsURLConnection;
//import javax.net.ssl.SSLContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import javax.net.*;
import javax.net.ssl.*;
import java.security.cert.*;


/**
 *
 * @author Ruwan
 */
public class LBS2 extends HttpServlet {

/** 
 * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
        LBS2 s=new LBS2();
        s.myReq();

    } finally {            
        out.close();
    }
}



public void myReq(){
  System.setProperty("https.proxyHost", "10.48.242.90");
  System.setProperty("https.proxyPort", "3128");
        String uri = "https://somthing.com/abc?username=USERNAME&password=PASWORD";

    try{
        SSLContext sslctx = SSLContext.getInstance("SSL");
        sslctx.init(null, new X509TrustManager[] { new MyTrustManager()}, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sslctx.getSocketFactory());
        URL url = new URL(uri);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.setDoOutput(true);
        con.connect();
        if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(new
            InputStreamReader(con.getInputStream()));
            String line;
            while((line = br.readLine()) != null) {
            System.out.println(line);
            }
            br.close();
        }
        con.disconnect();

        }
        catch(Exception e){
        System.out.println(e.toString());
        }
}


    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the +     sign on the left to edit the code.">
    /** 
 * Handles the HTTP <code>GET</code> method.
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    processRequest(request, response);
}

/** 
 * Handles the HTTP <code>POST</code> method.
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    processRequest(request, response);
}

/** 
 * Returns a short description of the servlet.
 * @return a String containing servlet description
 */
@Override
public String getServletInfo() {
    return "Short description";
}// </editor-fold>
}


class MyTrustManager implements X509TrustManager {
        @Override
            public void checkClientTrusted(X509Certificate[] chain, String
            authType) {
            }

        @Override
            public void checkServerTrusted(X509Certificate[] chain, String
            authType) {
            }

        @Override
            public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
 }    

Please help me to find the problem with SSL Certificat handling in this code thnks in advance

请帮我在此代码中找到 SSL 证书处理的问题 thnks 提前

回答by Nishant

Here this might help: (excerpts from http://code.naishe.in/2011/07/looks-like-article-no-more-unable-to.html)

这可能会有所帮助:(摘自http://code.naishe.in/2011/07/looks-like-article-no-more-unable-to.html

Some of you may be familiar with the (not very user friendly) exception message

  javax.net.ssl.SSLHandshakeException: 
  sun.security.validator.ValidatorException: PKIX path building failed:
  sun.security.provider.certpath.SunCertPathBuilderException:
  unable to find valid certification path to requested target

when trying to open an SSL connection to a host using JSSE. What this usually means is that the server is using a test certificate (possibly generated using keytool) rather than a certificate from a well known commercial Certification Authority such as Verisign or GoDaddy. Web browsers display warning dialogs in this case, but since JSSE cannot assume an interactive user is present it just throws an exception by default.

你们中的一些人可能熟悉(不是很用户友好)异常消息

  javax.net.ssl.SSLHandshakeException: 
  sun.security.validator.ValidatorException: PKIX path building failed:
  sun.security.provider.certpath.SunCertPathBuilderException:
  unable to find valid certification path to requested target

尝试使用 JSSE 打开与主机的 SSL 连接时。这通常意味着服务器使用的是测试证书(可能使用 keytool 生成),而不是来自知名商业证书颁发机构(如 Verisign 或 GoDaddy)的证书。在这种情况下,Web 浏览器会显示警告对话框,但由于 JSSE 无法假设存在交互式用户,因此默认情况下它只会引发异常。

PS: to long for a comment so added as an answer.

PS:渴望评论所以添加为答案。

回答by user207421

Your truststore does not trust the server's certificate. You need to export it from the server and install it at the client. The link others have posted shows a way to do that. The real problem is probably that the server is using a self-signed certificate instead of a CA-signed certificate, which just causes this problem for every client. Best solution is to spend the money and fix that.

您的信任库不信任服务器的证书。您需要将其从服务器导出并安装在客户端。其他人发布的链接显示了一种方法。真正的问题可能是服务器使用的是自签名证书而不是 CA 签名证书,这只会导致每个客户端出现此问题。最好的解决方案是花钱并解决这个问题。

回答by Ruwan Dissanayaka

Problem :Normal Java Program worked properly But webapp in tomcat server not worked properly although I used the same method/code

问题:普通 Java 程序运行正常但 tomcat 服务器中的 webapp 无法正常运行,尽管我使用了相同的方法/代码

Solution:So I configured the tomcat for SSL Certificate. If any one having the same problem. Just configure the tomcat for SSL Certificate.

解决方案:所以我配置了Tomcat的SSL证书。如果有人遇到同样的问题。只需为 SSL 证书配置 tomcat。

This will be helpful to configure tomcat for SSL Certificate

这将有助于为 SSL 证书配置 tomcat

Thank you for all the answers and comments. :)

感谢您的所有回答和评论。:)

回答by Stephan Oudmaijer

I had the same issue with a valid signed wildcard certificate from symantec.

我在使用来自赛门铁克的有效签名通配符证书时遇到了同样的问题。

First try running your java application with -Djavax.net.debug=SSLto see what is really going on.

首先尝试使用-Djavax.net.debug=SSL运行您的 Java 应用程序以查看实际情况。

I ended up importing the intermediate certificatewhich was causing the cert chain to break.

我最终导入了导致证书链中断的中间证书

I downloaded the missing intermediate cert from symantec (you can see the download link to the missing cert in the ssl handshake log: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cerin my case).

我从赛门铁克下载了缺少的中间证书(您可以在 ssl 握手日志中看到缺少证书的下载链接:http: //svrintl-g3-aia.verisign.com/SVRIntlG3.cer在我的情况下)。

And I imported the cert in the java keystore. After importing the intermediate certificate my wildcard ssl cert finally started working:

我在 java 密钥库中导入了证书。导入中间证书后,我的通配符 ssl 证书终于开始工作:

keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer

回答by Ted Shaw

you need return null to bypass Certificate validation

您需要返回 null 以绕过证书验证

    @Override
        public X509Certificate[] getAcceptedIssuers() {
        return null;
    }