java - 关于通过 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();
...这工作得很好。我发现这个网页暗示我需要做的就是切换HttpURLConnection
到HttpsURLConnection
,一切都应该正常工作。
另一方面,在我服务器的 cPanel 上,我发现了一个Lets Encrypt
部分,它使我能够将证书应用于我的服务器域。
PEM-Encoded Certificate
除其他外,设置它产生了PEM-Encoded Issuer
证书。
但后来我有点难过。我是否只是假设我上面的代码已更新以使用HttpsURLConnection
作品?我怎么知道它在工作。例如,如果我从我的 cPanel 中删除颁发的证书,那么上面的代码仍然有效......
发布后我发现的事情
如果我做我urlString
的 ahttp
它会抛出异常,而如果它是一个https
地址它不会,所以我猜这很好。
此外,这篇文章表明我走在正确的轨道上,因为我没有收到那里建议的任何错误,而且没有人提到这种方式是错误的做法。
可能感兴趣,它实际上指出“SSL 现在称为传输层安全性 (TLS)”,这已经简化了事情。
这看起来是一篇很棒的文章。我还注意到,除了 Lets Encrypt 选项之外,我们还必须在 cPanel 上设置 SSL/TLS。很有道理,原来没看到。更多:原来 Lets Encrypt 是一项免费服务,它为您提供自动证书以供使用,而不是从服务提供商处购买。但是,您也可以签署自己的免费证书,但不受任何受信任的证书颁发机构 (CA) 的“认可”。
解决方案
我通常使用如下方法使 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(...){}
推荐阅读
- unit-testing - 用于单元测试的弧
- xml - 处理嵌套节点的最佳方法(不同的名称,相同的内容)
- python-3.x - 使用 pyttsx3 将列表上的迭代结果保存为单个音频
- c++ - 房间在 SFML(地牢爬行者)中不断重叠
- rust - 尝试连接时出错:证书不受信任
- azure - ADF - 从数据流中获取随机样本数据
- javascript - 使用 Chai 的 Expect 接口测试部分对象属性
- api - 具有安全外部 API 消耗的最小前端 Web 应用程序
- flutter - Flutter 集成测试引发错误“null check operator used on a null value”
- python - 从一列到另一列分组列