Java中HTTP接口请求与HTTPS证书验证问题

HTTP是基于TCP/IP的应用层协议,简单、便捷。RESTFUL是一种基于HTTP的网络应用程序设计风格和开发方式,方便实现跨平台的业务接口。

HTTP请求

Java中通过HttpURLConnection可方便地进行HTTP请求:

String sendRequest(String strUrl, String strMethod, String strBody) {
    String strResult = "";
    try {
        URL url = new URL(strUrl);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod(strMethod);
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type", "application/json");

        if (strBody.length() > 0) { // Has body(for post-request)
            httpConn.setDoOutput(true);
            try (OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream(), StandardCharsets.UTF_8);
            ) {
                writer.write(strBody);
                writer.flush();
            }
        }

        // request now
        if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new IOException(httpConn.getResponseMessage());
        }

        try (InputStreamReader inReader = new InputStreamReader(httpConn.getInputStream());
             BufferedReader buffReader = new BufferedReader(inReader);
        ) {
            String strLine;
            while ((strLine = buffReader.readLine()) != null) {
                strResult += strLine;
            }
        }
    } catch (IOException ex) {
        _logger.error("sendRequest({}) fail: {}", strUrl, ex);
    }

    return strResult;
}

请求的头(Headers)与URL一起通过第一个参数传入,请求的方式(POST、GET等)通过第二个参数传入,body通过第三个参数传入。

证书验证

在使用HTTPS请求时,若服务器的证书不是第三方信任机构颁发的(如自签名证书等),则会验证失败,然后报错(类似‘unable to find valid certification path to requested target’)。

HTTPS通讯

客户端在使用HTTPS与服务器通讯的基本流程:

  • 客户端通过HTTPS与服务器建立SSL连接;
  • 服务器在收到请求后,发送自身证书给客户端;
  • 客户端收到证书后,会对证书做验证(通过证书信任列表);浏览器等一般会弹出提示框,而Java请求中若发现证书不可信,则会报上面错误;
  • 客户端与服务器协商SSL连接安全等级;
  • 客户端根据协商等级建立会话密钥,并利用证书中公钥加密后发送给服务器;
  • 服务器使用对应私钥解密出会话密钥;
  • 两端使用会话密钥加密进行通讯。

出错处理

通过重写TrustManager的checkClientTrusted(检查客户端证书信任)和checkServerTrusted(检查服务端证书验证)。以及HostnameVerifier的verify(校验)方法即可取消对证书的所有验证。

static HostnameVerifier _hv = new HostnameVerifier() {
    @Override
    public boolean verify(String host, SSLSession sslSession) {
        _logger.warn("Host: {} VS {}", host, sslSession.getPeerHost());
        return true;
    }
};
static TrustManager[] _trustCerts = new TrustManager[]{
        new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }

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

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

static {
    try {
        HttpsURLConnection.setDefaultHostnameVerifier(_hv);
        SSLContext ctxSSL = null;
        ctxSSL = SSLContext.getInstance("SSL");
        ctxSSL.init(null, _trustCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(ctxSSL.getSocketFactory());
    } catch (Exception e) {
        _logger.error("SSL context set fail: {}", e);
    }
}

类中static代码会在类初次加载时调用一次;因验证代码影响是全局的,只要执行过,所有后续的请求都会生效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值