https單向認證和雙向認證

一;單向認證java

瀏覽器訪問https單向認證:算法

1.服務器端提供服務器證書,驗證服務器身份。瀏覽器

2.由CA機構簽發的數字證書無需在客戶端(瀏覽器)「受信任證書中」導入,自簽名證書zlex.cer(服務器證書)需手動進行導入(證書驗證)tomcat

3.使用tomcat做爲服務器,須在tomcat的server.xml文件中配置SSL/TLS協議服務器

4.將簽發的數字證書zlex.cer導入到密鑰庫zlex.keystore中。將zlex.keystore放在tomcat的conf目錄下,並在serverlet.xml中配置SSL/TLS的單向認證。dom

5.此時就能夠經過瀏覽器訪問tomcat。若訪問失敗,還需在客戶端(瀏覽器)中導入根證書,以後就能夠成功訪問tomcat主頁,也能夠編寫jsp頁面,經過tomcat發佈,獲取https的相關信息,如數字證書的加密算法、密鑰長度jsp

 

java代碼訪問https單向認證:測試

1.只需得到服務器端的數字證書,並將其導入密鑰庫應用相應的java API 便可進行加密交互。加密

例子:url

package com.httpsDemo;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

// https單向訪問服務
public abstract class HTTPSCoder {
    // 1.協議:支持TLS和SSL協議
    public static final String PROTOCOL = "TLS";
    // 2.得到密鑰庫
    private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
        // 實例化密鑰庫
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        // 得到密鑰庫文件流
        FileInputStream is = new FileInputStream(keyStorePath);
        // 加載密鑰庫
        ks.load(is, password.toCharArray());
        // 關閉密鑰庫文件流
        is.close();
        return ks;
    }
    
    // 3.得到SSLSocketFactory
    private static SSLSocketFactory getSSLSocketFactory(String password, String keyStorepath, String trustStorePath) throws Exception {
        // 實例化密鑰庫工廠
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        // 得到密鑰庫
        KeyStore keyStore = getKeyStore(keyStorepath, password);
        // 初始化密鑰庫工廠
        keyManagerFactory.init(keyStore, password.toCharArray());
        
        // 實例化信任庫工廠
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 得到信任庫
        KeyStore trustStore = getKeyStore(trustStorePath, password);
        // 初始化信任庫
        trustManagerFactory.init(trustStore);
        
        // 實例化SSL上下文
        SSLContext ctx = SSLContext.getInstance(PROTOCOL);
        // 初始化SSL上下文
        ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        // 得到SSLSocketFactory
        return ctx.getSocketFactory();
        
    }
    
    // 4.爲HttpsURLConnection配置SSLSocketFactory
    public static void configSSLSocketFactory (HttpsURLConnection conn, String password, String keyStorePath, String trustStorePath ) throws Exception {
        // 得到SSLSocketFactory
        SSLSocketFactory sslSocketFactory = getSSLSocketFactory(password, keyStorePath, trustStorePath);
        // 設置SSLSocketFactory
        conn.setSSLSocketFactory(sslSocketFactory);
        
    }
    
    
    
    
    
}

測試:

package com.httpsDemo;

import java.io.DataInputStream;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

// https測試:內容傳輸時已經對加密解密進行了封裝操做,咱們沒必要去關心
public class HTTPSCoderTest {
    // 密鑰庫/信任庫密碼
    private static String password = "123456";
    // 密鑰庫文件路徑
    private static String keyStorePath = "D:/zlex.keystore";
    // 信任庫文件路徑
    private static String trustStorePath = "D:/zlex.keystore";
    // 訪問地址
    private static String httpsUrl = "https://www.zlex.org/ssl/";
    
    // https驗證
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        // 創建HTTPS鏈接
        URL url = new URL(httpsUrl);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        // 打開輸入輸出流
        conn.setDoInput(true);
        // 爲HttpsURLConnection配置SSLSocketFactory
        HTTPSCoder.configSSLSocketFactory(conn, password, keyStorePath, trustStorePath);
        // 鑑別內容長度(長度不等於-1說明鏈接成功)
        int length = conn.getContentLength();
        byte[] data = null;
        // 若是內容長度爲-1,則放棄解析
        if (length != -1) {
            DataInputStream dis = new DataInputStream(conn.getInputStream());
            data = new byte[length];
            dis.readFully(data);
            dis.close();
            System.err.println(new String(data));    
        }
        // 關閉鏈接
        conn.disconnect();
        // 驗證內容
        //assertNotNull(data);
        
    }

}

二:https雙向認證

1.使用的證書:ca.p12(根證書)、server.p12(服務端證書)、client.p12(客戶端證書)

2.將ca.p12證書、client.p12證書導入瀏覽器(和zlex.cer導入同樣)

3.進行服務器配置:將ca.p12和server.p12複製到tomcat的conf目錄下,同時經過在瀏覽器中導入ca.p12和client.p12文件

4.在tomcat的server.xml中配置雙向認證:scheme="https"     clientAute="true"(打開雙向驗證)。雙向認證服務端區分信任庫和密鑰庫。此時將server.p12做爲密鑰庫文件,ca.p12做爲信任庫文件

 

雙向認證代碼:

package com.httpsDemo;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

// https單向訪問服務
public abstract class HTTPSCoder {
    // 1.協議:支持TLS和SSL協議
    public static final String PROTOCOL = "TLS";
    // 2.得到密鑰庫
    private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
        // 實例化密鑰庫:使用PKCS#12格式的我的信息交換文件做爲密鑰庫和信任庫文件
        KeyStore ks = KeyStore.getInstance("PKCS12");
        // 得到密鑰庫文件流
        FileInputStream is = new FileInputStream(keyStorePath);
        // 加載密鑰庫
        ks.load(is, password.toCharArray());
        // 關閉密鑰庫文件流
        is.close();
        return ks;
    }
    
    // 3.得到SSLSocketFactory
    private static SSLSocketFactory getSSLSocketFactory(String password, String keyStorepath, String trustStorePath) throws Exception {
        // 實例化密鑰庫工廠
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        // 得到密鑰庫
        KeyStore keyStore = getKeyStore(keyStorepath, password);
        // 初始化密鑰庫工廠
        keyManagerFactory.init(keyStore, password.toCharArray());
        
        // 實例化信任庫工廠
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 得到信任庫
        KeyStore trustStore = getKeyStore(trustStorePath, password);
        // 初始化信任庫
        trustManagerFactory.init(trustStore);
        
        // 實例化SSL上下文
        SSLContext ctx = SSLContext.getInstance(PROTOCOL);
        // 初始化SSL上下文
        ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
        // 得到SSLSocketFactory
        return ctx.getSocketFactory();
        
    }
    
    // 4.爲HttpsURLConnection配置SSLSocketFactory
    public static void configSSLSocketFactory (HttpsURLConnection conn, String password, String keyStorePath, String trustStorePath ) throws Exception {
        // 得到SSLSocketFactory
        SSLSocketFactory sslSocketFactory = getSSLSocketFactory(password, keyStorePath, trustStorePath);
        // 設置SSLSocketFactory
        conn.setSSLSocketFactory(sslSocketFactory);
        
    }
    
    
    
    
    
}

測試:

package com.httpsDemo;

import java.io.DataInputStream;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

// https測試:內容傳輸時已經對加密解密進行了封裝操做,咱們沒必要去關心
public class HTTPSCoderTest {
    // 密鑰庫/信任庫密碼
    private static String password = "123456";
    // 密鑰庫文件路徑
    private static String keyStorePath = "D:/server.p12";
    // 信任庫文件路徑
    private static String trustStorePath = "D:/ca.p12";
    // 訪問地址
    private static String httpsUrl = "https://www.zlex.org/ssl/";
    
    // https驗證
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        // 創建HTTPS鏈接
        URL url = new URL(httpsUrl);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        // 打開輸入輸出流
        conn.setDoInput(true);
        // 爲HttpsURLConnection配置SSLSocketFactory
        HTTPSCoder.configSSLSocketFactory(conn, password, keyStorePath, trustStorePath);
        // 鑑別內容長度(長度不等於-1說明鏈接成功)
        int length = conn.getContentLength();
        byte[] data = null;
        // 若是內容長度爲-1,則放棄解析
        if (length != -1) {
            DataInputStream dis = new DataInputStream(conn.getInputStream());
            data = new byte[length];
            dis.readFully(data);
            dis.close();
            System.err.println(new String(data));    
        }
        // 關閉鏈接
        conn.disconnect();
        // 驗證內容
        //assertNotNull(data);
        
    }

}
相關文章
相關標籤/搜索