首页 > 代码库 > Tomcat容器https配置之双向认证

Tomcat容器https配置之双向认证

在上一篇https单向认证基础上(如果没看过的,请先移步:http://www.cnblogs.com/leafsunday/p/6885568.html),开始https双向认证之旅。

  • 生成客户端keystore(PKCS12格式,便于导入浏览器)

C:\Users\Administrator>keytool -genkeypair -alias client -keyalg RSA -keysize 1024 -keypass changeit -keystore d:/client.p12  -storetype PKCS12 -storepass changeit
您的名字与姓氏是什么?
  [Unknown]:  localhost
您的组织单位名称是什么?
  [Unknown]:  localhost
您的组织名称是什么?
  [Unknown]:  localhost
您所在的城市或区域名称是什么?
  [Unknown]:  hz
您所在的省/市/自治区名称是什么?
  [Unknown]:  zj
该单位的双字母国家/地区代码是什么?
  [Unknown]:  cn
CN=127.0.0.1, OU=localhost, O=localhost, L=hz, ST=zj, C=cn是否正确?
  [否]:  y
keypass 和 storepass保持一致
  •  

    导出客户端证书

 

C:\Users\Administrator>keytool -exportcert -alias client -file d:/client.cer -keystore d:/client.p12 -storetype PKCS12 -storepass changeit

 

  • 将客户端证书导入到服务端的环境中

C:\Users\Administrator>keytool -importcert -alias client -keystore %JAVA_HOME%\jre\lib\security\cacerts -storepass changeit -file d:/client.cer
  • 配置Tomcat

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="true" sslProtocol="TLS"
               keystoreFile="D:/server"
               keystorePass="changeit"/>

和单向认证不同 clientAuth 值要设置为true

  • 测试

  1. 浏览器访问则需要先将证书client.p12导入浏览器,Internet选项--》内容--》证书--》个人--》导入,然后访问https://localhost,确认证书,忽略警告继续浏览。
  2. httpclient访问
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Created by leafsunday on 2017/5/20 .
 */
public class HttpsTest {


    public static void main(String args[]) throws Exception{
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).build();
        HttpGet httpGet = new HttpGet("https://localhost");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        String httpStr = EntityUtils.toString(response.getEntity(), "utf-8");
        System.out.println(httpStr);
    }

    /**
     * 创建SSL安全连接
     *
     * @return
     */
    private static SSLConnectionSocketFactory createSSLConnSocketFactory() throws Exception {
        //初始化客户端证书 ---- 双向认证代码
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(new File("d:/client.p12")), "changeit".toCharArray());

        SSLContext sslContext = SSLContextBuilder.create()
                //加载客户端证书 用于服务端对客户端的认证 ---- 双向认证代码
                .loadKeyMaterial(keyStore, "changeit".toCharArray())

                /*
                //设置不校验服务端证书 不安全(不推荐)
                .loadTrustMaterial(null, new TrustStrategy() {
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return true;
                    }
                })
                */
                .build();

        return new SSLConnectionSocketFactory(sslContext
            /*
                //设置不校验hostname
                , new HostnameVerifier() {
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        }
        */
        );
    }
}

 

Tomcat容器https配置之双向认证