首页 > 解决方案 > 关于通过 HTTPS SSL(/TLS?)正确发布的说明

问题描述

SSL 的新手。我知道我应该使用 HTTPS SSL (/TLS?) 将我的数据从我的客户端应用程序发送到我的服务器。或者至少这是我想做的。

我之前在 Java 中的实现使用HttpURLConnection并看起来像这样:

    HttpURLConnection conn = null;

    try
    {
        URL url = new URL(urlString);
        conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        OutputStream os = conn.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
        osw.write(dataString);
        osw.flush();
        osw.close();
        os.close();
        conn.connect();

        if(conn.getResponseCode() != 200)
            throw new MyServerException();

        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        String output;
        StringBuilder sb = new StringBuilder();

        while ((output = br.readLine()) != null) {
            sb.append(output);
        }

        if(conn != null)
            conn.disconnect();

        return sb.toString();
    }
    catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    catch (ProtocolException e) {
        e.printStackTrace();
    }
    catch (MalformedURLException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        if(conn != null)
            conn.disconnect();
    }

    throw new MyServerException();

...这工作得很好。我发现这个网页暗示我需要做的就是切换HttpURLConnectionHttpsURLConnection,一切都应该正常工作。

另一方面,在我服务器的 cPanel 上,我发现了一个Lets Encrypt部分,它使我能够将证书应用于我的服务器域。

PEM-Encoded Certificate除其他外,设置它产生了PEM-Encoded Issuer证书。

但后来我有点难过。我是否只是假设我上面的代码已更新以使用HttpsURLConnection作品?我怎么知道它在工作。例如,如果我从我的 cPanel 中删除颁发的证书,那么上面的代码仍然有效......

发布后我发现的事情

如果我做我urlString的 ahttp它会抛出异常,而如果它是一个https地址它不会,所以我猜这很好。

此外,这篇文章表明我走在正确的轨道上,因为我没有收到那里建议的任何错误,而且没有人提到这种方式是错误的做法。

可能感兴趣,它实际上指出“SSL 现在称为传输层安全性 (TLS)”,这已经简化了事情。

这看起来是一篇很棒的文章。我还注意到,除了 Lets Encrypt 选项之外,我们还必须在 cPanel 上设置 SSL/TLS。很有道理,原来没看到。更多:原来 Lets Encrypt 是一项免费服务,它为您提供自动证书以供使用,而不是从服务提供商处购买。但是,您也可以签署自己的免费证书,但不受任何受信任的证书颁发机构 (CA) 的“认可”。

标签: javassl-certificatehttpsurlconnection

解决方案


我通常使用如下方法使 https url 连接信任任何证书。

try {
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, new X509TrustManager[]{new X509TrustManager() {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }

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

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
    }}, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch(NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch(KeyManagementException e) {
    e.printStackTrace();
}

并使用没有主机名的证书向服务器发出安全请求。

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
});

然后,您可以获得一个 HttpURLConnection 对象作为 HttpsURLConnection 对象。

HttpURLConnection connection = null;
try
{
    URL _url = new URL(url);
    String scheme = _url.getProtocol();

    if(scheme.equals("https")) {
       connection = (HttpsURLConnection)new URL(url).openConnection();
    }
 }catch(...){} 

推荐阅读