JAVA NIO MINA2调用大宝CA版本JSSE访问国密SSL安全通道服务的方法

系统要求
1. Windows系统、Linux系统、Mac系统
2. JDK7及以上
3. JDK使用无限制的安全策略文件

 

TcpGmSslClient.java代码

/**
 * @author https://www.doubleca.com
 */
package com.doubleca.security.gmssl.sample.mina2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.GeneralSecurityException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class TcpGmSslClient extends IoHandlerAdapter
{
    private IoConnector connector;
    private static IoSession session;
    private IoBuffer buffer = IoBuffer.allocate(8);
    private long t0;
    private long t1;
    private CountDownLatch counter;

    public TcpGmSslClient() throws GeneralSecurityException, IOException
    {
        this.connector = new NioSocketConnector();

        SSLContext sslContext = GmSslContextFactory.getInstance(false);
        SslFilter sslFilter = new SslFilter(sslContext);
        sslFilter.setUseClientMode(true);
        this.connector.getFilterChain().addFirst("sslFilter", sslFilter);

        this.connector.setHandler(this);
        ConnectFuture connFuture = this.connector.connect(new InetSocketAddress("localhost", 18567));

        connFuture.awaitUninterruptibly();

        session = connFuture.getSession();
    }

    public void exceptionCaught(IoSession session, Throwable cause) throws Exception
    {
        cause.printStackTrace();
    }

    public void messageReceived(IoSession session, Object message) throws Exception
    {
        long received = ((IoBuffer) message).getLong();
        if (received != this.counter.getCount())
        {
            System.out.println("Error !");
            session.closeNow();
        }
        else if (this.counter.getCount() == 0L)
        {
            this.t1 = System.currentTimeMillis();

            System.out.println("------------->  end " + (this.t1 - this.t0));
            session.closeNow();
        }
        else
        {
            this.counter.countDown();

            this.buffer.flip();
            this.buffer.putLong(this.counter.getCount());
            this.buffer.flip();
            session.write(this.buffer);
        }
    }

    public void messageSent(IoSession session, Object message) throws Exception
    {
        if (this.counter.getCount() % 5000L == 0L)
        {
            System.out.println("Sent " + this.counter + " messages");
        }
    }

    public void sessionClosed(IoSession session) throws Exception
    {
    }

    public void sessionCreated(IoSession session) throws Exception
    {
    }

    public void sessionIdle(IoSession session, IdleStatus status) throws Exception
    {
    }

    public void sessionOpened(IoSession session) throws Exception
    {
    }

    public static void main(String[] args) throws Exception
    {
        TcpGmSslClient client = new TcpGmSslClient();

        client.t0 = System.currentTimeMillis();
        client.counter = new CountDownLatch(50000);
        client.buffer.putLong(client.counter.getCount());
        client.buffer.flip();
        session.write(client.buffer);
        int nbSeconds = 0;
        while ((client.counter.getCount() > 0L) && (nbSeconds < 120))
        {
            client.counter.await(1L, TimeUnit.SECONDS);
            nbSeconds++;
        }
        client.connector.dispose(true);
    }

}
 

GmSslContextFactory.java代码

/**
 * @author https://www.doubleca.com
 */
package com.doubleca.security.gmssl.sample.mina2;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Security;

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

import doubleca.security.gmssl.provider.DoubleCASSE;
import doubleca.security.provider.DoubleCA;

/**
 *
 *
 */
public class GmSslContextFactory
{
    /**
     * Protocol to use.
     */
    private static final String PROTOCOL = "GMSSLv1.1";

    private static final String KEY_MANAGER_FACTORY_ALGORITHM;

    /**
     * 
     */
    private static DoubleCASSE dcsse = new DoubleCASSE();
    /**
     * 用终端授权请求编码去http://www.pplic.com申请授权数据
     */
    private static void generateLicRequest()
    {
        StringBuffer licRequest = new StringBuffer();
        int result = dcsse.generateLicRequest(licRequest);
        if (result == 0x70000000)
        {
            System.out.println("终端授权请求编码:");
            System.out.println(licRequest.toString());
        }
        else
        {
            System.out.println("终端授权请求编码出错,错误编号:0x" + Integer.toHexString(result));    
        }
    }
    /**
     * 用授权数据初始化dcsse
     */
    private static void initLic()
    {
        // 获得的本机授权数据,在http://www.pplic.com授权平台获取
        String licData = "ASeraPDybn/wwAABTGQnuKT71OrK0gnV/OSwjRcgHXJAtseX+Tu2kqOJCnT4r4b9/FUYOKXfJ3nsjDarus6mo+WPax6Z4W8ONonjro7Ql0WxJgIM234bdV2xBvv8pUkD/dffwZfkQ/HfjXsz4QH2+TQ0eWcUr4f2hnfNDxczJ+g88pWVUuCbcxTLWdCWW547Bp2TJ5FQt28zWxSTXqoJxXavYMffp1PnvBL9DOjKLFhqRdLVVsoiIVTsikGEgHeKrUsjmft01PqSd9ErqWEXsGpslzVzuVBjGtyQh6Arz3Ksy1wyipor+7y4KrsTuD9qxvfEjKdHm58p0BacfOHXfLe8XUKDLADIddfDyMIgAXAiUG8Zh+oRw0qDIuIgVgaRGcQ0SEWpXQbl2wCXye2B9Oa2Pr+9+/OWS4LbxWIiDOEbTA4kQT/lklQ3sfBZZJkXPJtmMQx0HgNcsrX6tkoiZC1G0c4mSkbq6k8R5dIS6KcEycS2SekKCqmNmC1yd9QC2iAXIG/pcTaGWuTzPWbU+6lfu0MMm4zL9po1wBORzpVqxsTh6hhe0URpxqPdNQOWHRp7PxaCRhJrZAh7/DiwulJwu7I42zbXdkncmwHHj07DCyJiUJScXz4tVaC/BgRV93ySirRh9gTjV61DM97pS43adyOA2U4cGNO7nm5b7JLKInE4ukuislJZHDB/5hiDRE/H48KPZNB/EsEZVcEgIXaAaRwf1jOG6pvM9qS6Pg==";
        dcsse.setLicData(licData);
        System.out.println("授权有效期:" + dcsse.getLicEndTime().toLocaleString());    
    }
    
    static
    {
        String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
        if (algorithm == null)
        {
            algorithm = KeyManagerFactory.getDefaultAlgorithm();
        }
        KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
        Security.addProvider(new DoubleCA());
        Security.addProvider(dcsse);
        initLic();
    }

    /**
     * GmSSL Server certificate keystore file name.
     * https://www.doubleca.com
     */
    private static final String DoubleCA_Server_KEYSTORE = "resources/SERVER.dcks";

    /**
     * GmSSL Client certificate keystore file name.
     * https://www.doubleca.com
     */
    private static final String DoubleCA_Client_KEYSTORE = "resources/CLIENT.dcks";
    
    /**
     * Bougus keystore password.
     */
    private static final char[] DCKS_PW = {'D', 'o', 'u', 'b', 'l', 'e', 'C', 'A'};

    private static SSLContext serverInstance = null;

    private static SSLContext clientInstance = null;

    /**
     * Get SSLContext singleton.
     * 
     * @return SSLContext
     * @throws java.security.GeneralSecurityException
     * @throws IOException 
     * 
     */
    public static SSLContext getInstance(boolean server) throws GeneralSecurityException, IOException
    {
        SSLContext retInstance = null;
        if (server)
        {
            synchronized (GmSslContextFactory.class)
            {
                if (serverInstance == null)
                {
                    try
                    {
                        serverInstance = createDoubleCAServerGmSslContext();
                    }
                    catch (Exception ioe)
                    {
                        throw new GeneralSecurityException("Can't create Server SSLContext:" + ioe);
                    }
                }
            }
            retInstance = serverInstance;
        }
        else
        {
            synchronized (GmSslContextFactory.class)
            {
                if (clientInstance == null)
                {
                    clientInstance = createDoubleCAClientGmSslContext(false);
                }
            }
            retInstance = clientInstance;
        }
        return retInstance;
    }

    private static SSLContext createDoubleCAServerGmSslContext() throws GeneralSecurityException, IOException
    {
        // Create keystore
        KeyStore ks = KeyStore.getInstance("DCKS", DoubleCA.PROVIDER_NAME);
        InputStream in = null;
        try
        {
            in = new FileInputStream(DoubleCA_Server_KEYSTORE);
            ks.load(in, DCKS_PW);
        }
        finally
        {
            if (in != null)
            {
                try
                {
                    in.close();
                }
                catch (IOException ignored)
                {
                }
            }
        }

        // Set up key manager factory to use our key store
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM, DoubleCASSE.PROVIDER_NAME);
        kmf.init(ks, DCKS_PW);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM, DoubleCASSE.PROVIDER_NAME);
        tmf.init(ks);

        // Initialize the SSLContext to work with our key managers.
        SSLContext sslContext = SSLContext.getInstance(PROTOCOL, DoubleCASSE.PROVIDER_NAME);
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        return sslContext;
    }

    private static SSLContext createDoubleCAClientGmSslContext(boolean clientAuth) throws GeneralSecurityException, IOException
    {
        SSLContext sc = SSLContext.getInstance(PROTOCOL, DoubleCASSE.PROVIDER_NAME);
        KeyManager[] clientCertManager = null;
        if (clientAuth == true)
        {
            // 双向认证
            // 客户端证书
            KeyStore sm2ClientKeyStore = KeyStore.getInstance("DCKS");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM, DoubleCASSE.PROVIDER_NAME);
            InputStream in = null;
            try
            {
                in = new FileInputStream(DoubleCA_Client_KEYSTORE);
                sm2ClientKeyStore.load(in, DCKS_PW);
            }
            finally
            {
                if (in != null)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException ignored)
                    {
                    }
                }
            }
            kmf.init(sm2ClientKeyStore, DCKS_PW);
            clientCertManager = kmf.getKeyManagers();
        }
        // 信任管理器,服务端根证书要放在这里,否则需要忽略服务器证书的信任
        KeyStore sm2TrustKeyStore = KeyStore.getInstance("DCKS");
        InputStream in = null;
        try
        {
            in = new FileInputStream(DoubleCA_Client_KEYSTORE);
            sm2TrustKeyStore.load(in, DCKS_PW);
        }
        finally
        {
            if (in != null)
            {
                try
                {
                    in.close();
                }
                catch (IOException ignored)
                {
                }
            }
        }
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM, DoubleCASSE.PROVIDER_NAME);
        tmf.init(sm2TrustKeyStore);
        sc.init(clientCertManager, tmf.getTrustManagers(), null);
        return sc;
    }
}
 

GmTrustManagerFactory.java代码

/**
 * @author https://www.doubleca.com
 */
package com.doubleca.security.gmssl.sample.mina2;

import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;

/**
 * @author https://www.doubleca.com
 *
 */
class GmTrustManagerFactory extends TrustManagerFactorySpi
{
    static final X509TrustManager X509 = new X509TrustManager()
    {
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
        {
        }

        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
        {
        }

        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[0];
        }
    };

    static final TrustManager[] X509_MANAGERS = new TrustManager[]{X509};

    public GmTrustManagerFactory()
    {
    }

    @Override
    protected TrustManager[] engineGetTrustManagers()
    {
        return X509_MANAGERS;
    }

    @Override
    protected void engineInit(KeyStore keystore) throws KeyStoreException
    {
        // noop
    }

    @Override
    protected void engineInit(ManagerFactoryParameters managerFactoryParameters) throws InvalidAlgorithmParameterException
    {
        // noop
    }

}
 


运行结果:

 ------ http://www.DoubleCA.com ---- 大宝CA ------ 
 -------       Watchdata & DoubleCA       ------- 

授权有效期:2999-2-20 1:01:01
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 50000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 45000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 40000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 35000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 30000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 25000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 20000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 15000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 10000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 5000] messages
Sent java.util.concurrent.CountDownLatch@6cf56dcc[Count = 0] messages

 

DCKS国密SSL通信证书和密钥文件在 大宝CA 网站上免费申请
国密SSL的JAR包需要授权使用,generateLicRequest函数生成终端授权请求编码,获取到授权数据放在initLic函数中即可完成授权,申请授权数据的具体步骤:


1. 访问 PP商业软件自主授权平台

2. 点击“应用方入口”

3. “软件1编号”填写:66-61F74672E9534ACEAF86EEFB8D8E75D0,免费授权码数量有限,获取请联系QQ:1337588982,将授权码写在“授权码”输入框内,“终端请求授权编码”框内复制generateLicRequest函数生成的终端授权请求编码

4. 提交授权请求后页面会生成授权数据,将授权数据复制到initLic函数中即可完成授权

最新版本JAVA NIO MINA2调用大宝CA版本JSSE访问国密SSL安全通道的JAR包和示例代码下载地址:https://download.csdn.net/download/upset_ming/11453849

授权码保留好,如果授权数据丢失,可凭授权码在 PP商业软件自主授权平台 回授权数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值