java实现ssl双向认证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhr562343414/article/details/66476143

使用httpclient实现双向认证

转载自:http://www.blogjava.net/itvincent/articles/330988.html

1、生成服务器端证书
keytool -genkey -keyalg RSA -dname “cn=localhost,ou=sango,o=none,l=china,st=beijing,c=cn” -alias server -keypass password -keystore server.jks -storepass password -validity 3650

keytool -genkey -keyalg RSA -dname “cn=localhost,ou=sango,o=none,l=china,st=beijing,c=cn” -alias server -keypass password -keystore server.jks -storepass password -validity 3650

2、生成客户端证书
keytool -genkey -keyalg RSA -dname “cn=sango,ou=sango,o=none,l=china,st=beijing,c=cn” -alias custom -storetype PKCS12 -keypass password -keystore custom.p12 -storepass password -validity 3650

keytool -genkey -keyalg RSA -dname “cn=sango,ou=sango,o=none,l=china,st=beijing,c=cn” -alias custom -storetype PKCS12 -keypass password -keystore custom.p12 -storepass password -validity 3650
客户端的CN可以是任意值。

3、由于是双向SSL认证,服务器必须要信任客户端证书,因此,必须把客户端证书添加为服务器的信任认证。由于不能直接将PKCS12格式的证书库导入,我们必须先把客户端证书导出为一个单独的CER文件,使用如下命令,先把客户端证书导出为一个单独的cer文件:
Java代码
keytool -export -alias custom -file custom.cer -keystore custom.p12 -storepass password -storetype PKCS12 -rfc

keytool -export -alias custom -file custom.cer -keystore custom.p12 -storepass password -storetype PKCS12 -rfc
然后,添加客户端证书到服务器中(将已签名数字证书导入密钥库)
Java代码
keytool -import -v -alias custom -file custom.cer -keystore server.jks -storepass password

keytool -import -v -alias custom -file custom.cer -keystore server.jks -storepass password
4、查看证书内容
Java代码
keytool -list -v -keystore server.jks -storepass password

keytool -list -v -keystore server.jks -storepass password
5、配置tomcat service.xml文件
Xml代码

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
maxThreads="150" scheme="https" secure="true" 
clientAuth="true" sslProtocol="TLS" 
keystoreFile="D:/server.jks" keystorePass="password" 
truststoreFile="D:/server.jks" truststorePass="password" 
/>

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="D:/server.jks" keystorePass="password"
truststoreFile="D:/server.jks" truststorePass="password"
/>

clientAuth=”true”表示双向认证
6、导入客户端证书到浏览器
双向认证需要强制验证客户端证书。双击“custom.p12”即可将证书导入至IE

7、java代码实现
下面分别用httpclient 3.x 和httpclient 4.x 实现

httpclient 3.x 实现ssl双向认证

package com.spdb.httpstest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;

public class httpsclient {

    public static HttpClient getHttpClient() throws Exception{
        Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
        Protocol.registerProtocol("https", myhttps);
        HttpClient httpclient = new HttpClient();
        //设置代理
        httpclient.getHostConfiguration().setProxy("10.112.24.30", 8019);
        //设置ssl证书
//      httpclient.getHostConfiguration().setHost("sandbox.99bill.com", 9445, myhttps);
        return httpclient;
    }

    public static class MySSLSocketFactory implements SecureProtocolSocketFactory {
        private static SSLContext SSLCONTEXT = null;
        private static SSLContext createSSLContext() {
            try {
//              这里根据证书类型,可以是jks、pkcs12,我们这里用jks
//              KeyStore keystore = KeyStore.getInstance("PKCS12");
//              FileInputStream ksInstream = new FileInputStream(new File("D:\\client.p12"));

                KeyStore keystore = KeyStore.getInstance("JKS");
                FileInputStream ksInstream = new FileInputStream(new File("C:\\Users\\asus\\Desktop\\Desktop\\10411004511201290.jks"));//客户端私钥 vpos123

                KeyStore trustStore = KeyStore.getInstance("JKS");
                FileInputStream trustInstream = new FileInputStream(new File("C:\\Users\\asus\\Desktop\\Desktop\\publicKey.jks"));//服务端端公钥 111111
                try {
                    keystore.load(ksInstream, "vpos123".toCharArray());
                    trustStore.load(trustInstream, "111111".toCharArray());
                } finally {
                    if (ksInstream != null)
                        ksInstream.close();
                    if (trustInstream!=null)
                        trustInstream.close();
                }
                KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                keyManagerFactory.init(keystore, "vpos123".toCharArray());
                trustManagerFactory.init(trustStore);
                KeyManager[] keymanagers=keyManagerFactory.getKeyManagers();
                TrustManager[] trustmanagers = trustManagerFactory.getTrustManagers();
                SSLContext sslcontext = SSLContext.getInstance("TLS");
                sslcontext.init(keymanagers, trustmanagers, null);
                return sslcontext;
            } catch (Exception ex) {
                throw new IllegalStateException(ex.getMessage());
            }

        }

        private static SSLContext getSSLContext() {
            if (SSLCONTEXT == null) {
                SSLCONTEXT = createSSLContext();
            }
            return SSLCONTEXT;
        }

        public MySSLSocketFactory() {
            super();
        }

        public Socket createSocket(final String host, final int port,
                final InetAddress localAddress, final int localPort,
                final HttpConnectionParams params) throws IOException,
                UnknownHostException, ConnectTimeoutException {
            if (params == null) {
                throw new IllegalArgumentException("Parameters may not be null");
            }
            int timeout = params.getConnectionTimeout();
            if (timeout == 0) {
                return createSocket(host, port, localAddress, localPort);
            } else {
                // To be eventually deprecated when migrated to Java 1.4 or above
                return ControllerThreadSocketFactory.createSocket(this, host, port,
                        localAddress, localPort, timeout);
            }
        }

        public Socket createSocket(String host, int port, InetAddress clientHost,
                int clientPort) throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(host, port,
                    clientHost, clientPort);
        }

        public Socket createSocket(String host, int port) throws IOException,
                UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(host, port);
        }

        public Socket createSocket(Socket socket, String host, int port,
                boolean autoClose) throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host,
                    port, autoClose);
        }
    }


    public static void main(String[] args) throws Exception {
        HttpClient httpclient = getHttpClient();
        GetMethod get = new GetMethod("https://sandbox.99bill.com:9445/cnp/query_cardinfo");//https://sandbox.99bill.com:9445/cnp/query_cardinfo
        String va = "812123445110018:vpos123";
        String decode = "Basic " + new String(Base64.encodeBase64(va.getBytes()));
        get.addRequestHeader("Authorization", decode);
        httpclient.executeMethod(get);
        System.out.println(get.getStatusCode());
    }

}

httpclient 4.x 实现ssl双向认证

package com.spdb.httpstest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

public class https4client {

    public static void main(String[] args) throws Exception {
        HttpClient httpclient = getHttpClient();
        HttpPost post = new HttpPost("https://sandbox.99bill.com:9445/cnp/query_cardinfo");
        String va = "812123445110018:vpos123";
        String decode = "Basic " + new String(Base64.encodeBase64(va.getBytes()));
//      post.addHeader("Authorization",decode);
//      post.addHeader("Content-Type", "application/json;charset=utf-8");
        String data = "test";
//      post.setEntity(new StringEntity(data,"utf-8"));
        HttpResponse rsp = httpclient.execute(post);
        System.out.println(rsp.getStatusLine().getStatusCode());
    }

    public static HttpClient getHttpClient() throws Exception{
        //设置http参数
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");
        HttpProtocolParams.setUseExpectContinue(params, true);

        HttpConnectionParams.setConnectionTimeout(params, 5000);//连接超时
        HttpConnectionParams.setSoTimeout(params, 5000);//请求超时

        SchemeRegistry schReg = new SchemeRegistry();
        schReg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));

        SSLSocketFactory sf = getBidirectionalSSL();
        schReg.register(new Scheme("https", 443, sf));

        PoolingClientConnectionManager pccm = new PoolingClientConnectionManager(
                schReg);
        pccm.setMaxTotal(100); // 客户端总并行链接最大数
        pccm.setDefaultMaxPerRoute(20); // 发送到指定主机的最大连接数
        DefaultHttpClient httpclient = new DefaultHttpClient(pccm, params);7645

        //设置代理
        HttpHost proxy = new HttpHost("10.112.24.30", 8019); 
        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        return httpclient;
    }

    /**
     * 双向ssl 设置客户端证书
     * @param httpParams
     * @return
     * @throws ConnectToThirdPayException
     */
    public static SSLSocketFactory getBidirectionalSSL() throws Exception {

        //第三方机构颁发给我行的私钥证书
        File certFile = new File("C:\\Users\\asus\\Desktop\\Desktop\\10411004511201290.jks");
        KeyStore ks = null;
        try {
            ks = KeyStore.getInstance("JKS");
        } catch (KeyStoreException e) {
            throw new Exception(e);
        }
        try {
            ks.load(new FileInputStream(certFile),"vpos123".toCharArray());
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        } catch (CertificateException e) {
            throw new Exception(e);
        } catch (FileNotFoundException e) {
            throw new Exception(e);
        } catch (IOException e) {
            throw new Exception(e);
        }
        KeyManagerFactory kmf = null;
        try {
            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        }
        try {
            kmf.init(ks, "vpos123".toCharArray());
        } catch (UnrecoverableKeyException e) {
            throw new Exception(e);
        } catch (KeyStoreException e) {
            throw new Exception(e);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        }

        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS");
        } catch (NoSuchAlgorithmException e) {
            throw new Exception(e);
        }

        try {
            sslContext.init(kmf.getKeyManagers(), getTrustManager(), null);
        } catch (KeyManagementException e) {
            throw new Exception(e);
        } catch (Exception e) {
            throw new Exception(e);
        }
        SSLSocketFactory factory = new SSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        return factory;
    }

    /**
     * 双向SSL 认证服务器的证书
     * @param httpParams
     * @return
     * @throws Exception
     */
    public static TrustManager[] getTrustManager() throws Exception{

        TrustManager[] trustManager=null;
        String publicKey = "C:\\Users\\asus\\Desktop\\Desktop\\publicKey.jks";

        if(null ==publicKey ||"".equals(publicKey)){

        }else{
            //第三方机构服务器的公钥证书
            File publicFile = new File(publicKey);// 快钱证书
            KeyStore pks = KeyStore.getInstance("JKS");
            pks.load(new FileInputStream(publicFile), "111111".toCharArray());
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            tmf.init(pks);
            trustManager = tmf.getTrustManagers();
        }

        return trustManager;
    }

}
展开阅读全文

没有更多推荐了,返回首页