https单向认证和双向认证

一;单向认证

浏览器访问https单向认证:

1.服务器端提供服务器证书,验证服务器身份。

2.由CA机构签发的数字证书无需在客户端(浏览器)“受信任证书中”导入,自签名证书zlex.cer(服务器证书)需手动进行导入(证书验证)

3.使用tomcat作为服务器,须在tomcat的server.xml文件中配置SSL/TLS协议

4.将签发的数字证书zlex.cer导入到密钥库zlex.keystore中。将zlex.keystore放在tomcat的conf目录下,并在serverlet.xml中配置SSL/TLS的单向认证。

5.此时就可以通过浏览器访问tomcat。若访问失败,还需在客户端(浏览器)中导入根证书,之后就可以成功访问tomcat主页,也可以编写jsp页面,通过tomcat发布,获取https的相关信息,如数字证书的加密算法、密钥长度

 

java代码访问https单向认证:

1.只需获得服务器端的数字证书,并将其导入密钥库应用相应的java API 即可进行加密交互。

例子:

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);
        
    }

}

 

posted @ 2018-08-20 01:00  爱吃空心菜  阅读(1279)  评论(0编辑  收藏  举报