【轉】java
https協議對於開發者而言其實只是多了一步證書驗證的過程。這個證書正常狀況下被jdk/jre/security/cacerts所管理。裏面證書包含兩種狀況:json
一、機構所頒發的被認證的證書,這種證書的網站在瀏覽器訪問時https頭顯示爲綠色如百度瀏覽器
二、我的所設定的證書,這種證書的網站在瀏覽器裏https頭顯示爲紅色×,且須要點擊信任該網站才能繼續訪問。而點擊信任這一步的操做就是咱們在java代碼訪問https網站時區別於http請求須要作的事情。session
因此JAVA發送Https請求有兩種狀況,三種解決辦法:app
第一種狀況:Https網站的證書爲機構所頒發的被認證的證書,這種狀況下和http請求如出一轍,無需作任何改變,用HttpsURLConnection或者HttpURLConnection均可以dom
- [java] view plain copy
- 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");
- //必須設置false,不然會自動redirect到重定向後的地址
- conn.setInstanceFollowRedirects(false);
- conn.connect();
- String result = getReturn(conn);
- }
-
- /*請求url獲取返回的內容*/
- public static String getReturn(HttpURLConnection 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;
- }
- }
第二種狀況:我的所設定的證書,這種證書默認不被信任,須要咱們本身選擇信任,信任的辦法有兩種:ide
A、將證書導入java的運行環境中網站
- 從該網站下載或者從網站開發者出獲取證書cacert.crt
- 運行命令將證書導入java運行環境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file cacert.crt -alias xxx
- 完成。java代碼中發送https的請求和http同樣,同第一種狀況。
B、忽略證書驗證過程,忽略以後任何Https協議網站皆能正常訪問,同第一種狀況this
- [java] view plain copy
- import java.security.cert.CertificateException;
- import java.security.cert.X509Certificate;
- import javax.net.ssl.X509TrustManager;
- 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() {
- // TODO Auto-generated method stub
- return null;
- }
- }
- [java] view plain copy
- 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 url = new URL("https://xxxx");
- HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
- public boolean verify(String s, SSLSession sslsession) {
- System.out.println("WARNING: Hostname is not matched for cert.");
- return true;
- }
- };
- HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
- HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
- //以後任何Https協議網站皆能正常訪問,同第一種狀況
- }
C、java代碼中加載證書,必須使用HttpsURLConnection方式url
- 從網站開發者出獲取生成證書的密鑰庫cacert.keystore
- [java] view plain copy
- 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 {
- /*
- * The default X509TrustManager returned by SunX509. We'll delegate
- * decisions to it, and fall back to the logic in this class if the
- * default X509TrustManager doesn't trust it.
- */
- X509TrustManager sunJSSEX509TrustManager;
- MyX509TrustManager() throws Exception {
- // create a "default" JSSE X509TrustManager.
- 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();
- /*
- * Iterate over the returned trustmanagers, look
- * for an instance of X509TrustManager. If found,
- * use that as our "default" trust manager.
- */
- for (int i = 0; i < tms.length; i++) {
- if (tms[i] instanceof X509TrustManager) {
- sunJSSEX509TrustManager = (X509TrustManager) tms[i];
- return;
- }
- }
- /*
- * Find some other way to initialize, or else we have to fail the
- * constructor.
- */
- throw new Exception("Couldn't initialize");
- }
- /*
- * Delegate to the default trust manager.
- */
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- try {
- sunJSSEX509TrustManager.checkClientTrusted(chain, authType);
- } catch (CertificateException excep) {
- // do any special handling here, or rethrow exception.
- }
- }
- /*
- * Delegate to the default trust manager.
- */
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- try {
- sunJSSEX509TrustManager.checkServerTrusted(chain, authType);
- } catch (CertificateException excep) {
- /*
- * Possibly pop up a dialog box asking whether to trust the
- * cert chain.
- */
- }
- }
- /*
- * Merely pass this through.
- */
- public X509Certificate[] getAcceptedIssuers() {
- return sunJSSEX509TrustManager.getAcceptedIssuers();
- }
- }
- [java] view plain copy
-
[java] view plain copy
- 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");
- //必須設置false,不然會自動redirect到重定向後的地址
- conn.setInstanceFollowRedirects(false);
- conn.connect();
- String result = getReturn(conn);
- }
-
- /*請求url獲取返回的內容*/
- 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;
- }
- }