https 协议对於开发者而言其实只是多了一步证书验证的过程,这个证书正常情况下被 jdk/jre/security/cacerts 所管理,里面证书包含两种情况:
1、机构所颁发的被认证的证书,这种证书的网站在浏览器访问时 https 头显示爲绿色
2、个人所设定的证书,这种证书的网站在浏览器里 https 头显示爲红色 ×,且需要点击信任该网站才能继续访问,。而点击信任这一步的操作就是我们在 java 代码访问 https 网站时区别於 http 请求需要做的事情。
所以 JAVA 发送 https 请求有两种情况,三种解决办法:
第一种情况:https 网站的证书爲机构所颁发的被认证的证书,这种情况下和 http 请求一模一样无需做任何改变,用 HttpsURLConnection 或者 HttpURLConnection 都可以
public static void main(String[] args) throws Exception{
URL serverUrl = new URL("https://xxxx");
HttpURLConnection conn =
(HttpURLConnection) serverUrl.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
conn.setInstanceFollowRedirects(false);
conn.connect();
String result = Sender.getReturn(conn);
}
public static String getReturn(HttpURLConnection connection)
throws Exception{
StringBuffer buffer = new StringBuffer();
try(InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader =
new InputStreamReader(inputStream,
java.lang.invoke.ConstantInfo.CHARSET);
BufferedReader bufferedReader =
new BufferedReader(inputStreamReader);) {
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
String result = buffer.toString();
return result;
}
}
第二种情况:个人所设定的证书,这种证书默认不被信任,需要我们自己选择信任,信任的办法有两种
A、将证书导入java的运行环境中
从该网站下载或者从网站开发者出获取证书 cacert.crt 运行命令将证书导入 java 运行环境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file cacert.crt -alias xxx
完成,java 代码中发送 https 的请求和 http 一样,同第一种情况。
B、忽略证书验证过程,忽略之後任何 https协议网站皆能正常访问,同第一种情况
import java.net.URL;
import java.security.cert.*;
import javax.net.ssl.*;
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate certificates[],
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] ax509certificate,
String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
public static void main(String[] args) throws Exception {
SSLContext sc = SSLContext.getInstance("TLSv1.2", "SunJSSE");
sc.init(null,
new TrustManager[] {new MyX509TrustManager() },
new java.security.SecureRandom());
SSLSocketFactory ssf = sc.getSocketFactory();
URL url = new URL("https://xxx.com.tw");
HttpsURLConnection httpsConn =
(HttpsURLConnection) url.openConnection();
HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
public boolean verify(String s, SSLSession sslsession) {
System.out.println(
"WARNING: Hostname is not matched for cert."
);
return true;
}
};
httpsConn.setDefaultHostnameVerifier(ignoreHostnameVerifier);
httpsConn.setDefaultSSLSocketFactory(ssf);
}
C、java 代码中加载证书,必须使用 HttpsURLConnection 方式,从网站开发者出获取生成证书的密钥库 cacert.keystore
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
X509TrustManager sunJSSEX509TrustManager;
MyX509TrustManager() throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("cancert.keystore"),
"changeit".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("SunX509", "SunJSSE");
tmf.init(ks);
TrustManager tms [] = tmf.getTrustManagers();
for (int i = 0; i < tms.length; i++) {
if (tms[i] instanceof X509TrustManager) {
sunJSSEX509TrustManager = (X509TrustManager) tms[i];
return;
}
}
throw new Exception("Couldn't initialize");
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException excep) {
}
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
try {
sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException excep) {
}
}
public X509Certificate[] getAcceptedIssuers() {
return sunJSSEX509TrustManager.getAcceptedIssuers();
}
}
public static void main(String[] args) throws Exception {
SSLContext sslcontext =
SSLContext.getInstance("SSL","SunJSSE");
sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()},
new java.security.SecureRandom());
URL serverUrl = new URL("https://xxxx");
HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();
conn.setSSLSocketFactory(sslcontext.getSocketFactory());
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
conn.setInstanceFollowRedirects(false);
conn.connect();
String result = getReturn(conn);
}
public static String getReturn(HttpsURLConnection connection)
throws IOException {
StringBuffer buffer = new StringBuffer();
try (InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader =
new InputStreamReader(inputStream,
ConstantInfo.CHARSET);
BufferedReader bufferedReader =
new BufferedReader(inputStreamReader);
)
{
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
String result = buffer.toString();
return result;
}
}
前言 本文说明取得历史交易资料。 程序实作 取得历史tick资料 tick代表每一笔成交纪录。 # ...
由wiki(https://zh.wikipedia.org/wiki/JSON) 可以知道JSON...
你可能精心写了一段广告,但最後发现被 Google 拒登,但别担心,这个情况,也许每个人都曾经历过。...
前言 前几天不管是讲怎麽把 Dockerfile 写好、还是做弱点扫描,基本上都是在确保 Docke...
安装并部署 Livewire 的步骤没有很多,照着做不用三分钟就能完成罗!今天一样是照着官方文件带大...