基于HTTPS的双向认证实现

来源:互联网 发布:贵阳广电网络客服电话 编辑:程序博客网 时间:2024/05/17 18:12

1.生成服务器证书

    keytool -genkey -keyalg RSA  -alias server  -keystore server.jks   -validity 3650

2.生成客户端证书

 3.把客户端证书导出为一个单独的cer文件:

keytool -export -alias custom -file custom.cer -keystore custom.p12 -storepass 111111 -storetype  PKCS12 -rfc

4.添加客户端证书到服务器中(将已签名数字证书导入密钥库)
keytool -import -v -alias custom -file custom.cer -keystore server.jks -storepass 111111
5.配置tomcat ssl,在tomcat/conf/server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
    maxThreads="150" scheme="https" secure="true"
    clientAuth="true" sslProtocol="TLS"
 truststoreType="JKS"
    keystoreFile="D:/keystory/server.jks" keystorePass="111111"
    truststoreFile="D:/keystory/server.jks" truststorePass="111111"/>
6.客户端编写
   // 获取证书路径
   File certFile = new File("D:/keystory/server.jks");
   // File certFile = new
   // File("D://hui.ding/workspace/DH_QuickPay/src/10411004511201290.jks");
   // 访问Java密钥库,JKS是keytool创建的Java密钥库,保存密钥。
   KeyStore ks;
   ks = KeyStore.getInstance("jks");
   ks.load(new FileInputStream(certFile),"111111".toCharArray());
   // 创建用于管理JKS密钥库的密钥管理器
   KeyManagerFactory kmf = KeyManagerFactory
     .getInstance(KeyManagerFactory.getDefaultAlgorithm());
   // 初始化证书
   kmf.init(ks, "111111".toCharArray());
   // 同位体验证信任决策源//同位体验证可信任的证书来源
   TrustManager[] tm = { new MyX509TrustManager() };
   //设置系统属性
   System.setProperty ("jsse.enableSNIExtension", "false");
   // 初始化安全套接字
   SSLContext sslContext = SSLContext.getInstance("SSL");
   // 初始化SSL环境。第二个参数是告诉JSSE使用的可信任证书的来源,设置为null是从javax.net.ssl.trustStore中获得证书。
   // 第三个参数是JSSE生成的随机数,这个参数将影响系统的安全性,设置为null是个好选择,可以保证JSSE的安全性。
   sslContext.init(kmf.getKeyManagers(), tm, null);
   // 根据上面配置的SSL上下文来产生SSLSocketFactory,与通常的产生方法不同
   SSLSocketFactory factory = sslContext.getSocketFactory();
   URL realUrl = new URL(TEST_URL);
   // 打开和URL之间的连接
   HttpsURLConnection conn = (HttpsURLConnection) realUrl
     .openConnection();
   // 创建安全的连接套接字
   conn.setSSLSocketFactory(factory);
   // 发送POST请求必须设置如下两行,使用 URL 连接进行输出、入
   conn.setDoOutput(true);
   conn.setDoInput(true);
   // 设置URL连接的超时时限
   conn.setReadTimeout(20000);
   // 设置通用的请求属性
//   String authString = entity.getMembercode() + ":" + entity.getVpos();
//   String auth = "Basic "
//     + Base64Binrary.encodeBase64Binrary(authString.getBytes());
//   conn.setRequestProperty("Authorization", auth);
   // 获取URLConnection对象对应的输出流
   
   conn.addRequestProperty("Content-type", "application/json");
   
   out = conn.getOutputStream();
   // 发送请求参数
   out.write(message.getBytes());
   // flush 输出流的缓冲
   out.flush();
   // 得到服务端返回
   InputStream is = conn.getInputStream();
   
   if (is != null && !"".equals(is)) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] receiveBuffer = new byte[2048];// 缓冲区长度
    int readBytesSize = is.read(receiveBuffer);// 读取数据长度,InputStream要读取的数据长度一定要小于等于缓冲区中的字节数
    //System.out.println("#######readBytesSize:" + readBytesSize);
    while (readBytesSize != -1) {// 判断流是否位于文件末尾而没有可用的字节
     bos.write(receiveBuffer, 0, readBytesSize);// 从receiveBuffer内存处的0偏移开始写,写与readBytesSize长度相等的字节
     readBytesSize = is.read(receiveBuffer);
     //System.out.println("#######bos:" + bos);
    }
    reqData = new String(bos.toByteArray(), "UTF-8");// 编码后的tr2报文
   }


0 0
原创粉丝点击