你的位置:首页 > ASP.net教程

[ASP.net教程]https双向认证demo


阅读此文首先需要具备数据加解密,公钥,私钥,签名,证书等基础知识。

通信服务端:使用tomcat

通信客户端:使用apache httpclient 4.5.1

1. 服务端操作

1.keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:\servesert\tomcat.keystore -validity 36500终端问答的参数:CN=helloworld.com, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownkeypassword 123456 storepassword 123456这步生成服务端的私钥和证书。 keystore是一个秘钥和证书的容器,里面可以装多个秘钥和证书。alias是一个keystore里证书或秘钥的唯一的识别id。CN=helloworld.com是服务端的域名,做测试时,客户端机器需要配置helloworld.com的hosts。keytool -list -v -keystore D:\servesert\tomcat.keystore 
查看该keystore里的证书和私钥。
keytool -keystore D:\servesert\tomcat.keystore -export -alias tomcat -file D:\servesert\tomcat.cer
将tomcat.keystore这个秘钥库里alias为tomcat的公钥导出为证书,这个证书将添加到客户端的受信任秘钥库中。

2.客户端操作

keytool -genkey -v -alias me -keyalg RSA -keystore D:\cert\me.keystore -validity 36500CN=hello, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknownkeypassword 123456 storepassword 123456生成客户端秘钥,CN名字可以随便填keytool -import -v -alias tomcat -file D:\servesert\tomcat.cer -keystore D:\cert\trust.keystore
将服务端导出的证书添加到客户端受信任的秘钥库中。

keytool -list -v -keystore D:\cert\me.keystore
keytool -list -v -keystore D:\cert\trust.keystore

keytool -keystore D:\cert\me.keystore -export -alias me -file D:\cert\me.cer 将客户端私钥库中的客户端证书导出,之后会添加到服务端的受信任证书库。

3.服务端操作

keytool -import -v -alias me -file D:\cert\me.cer -keystore D:\servecert\trust.keystore将客户端的证书导入服务器的受信任证书库

4.tomcat server.

 <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"        maxThreads="150" SSLEnabled="true" scheme="https" secure="true"        clientAuth="true" sslProtocol="TLS" keystoreFile="D:\\servesert\\tomcat.keystore"        keystorePass="123456" truststoreFile="D:\\servesert\\trust.keystore"        truststorePass="123456" /> 

5.java客户端代码

package com.xy;import org.apache.http.HttpEntity;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.conn.ssl.TrustSelfSignedStrategy;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.apache.http.ssl.SSLContexts;import javax.net.ssl.SSLContext;import java.io.File;import java.io.IOException;import java.security.KeyManagementException;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.UnrecoverableKeyException;import java.security.cert.CertificateException;/** * Created by xiaxia on 2015/11/4. */public class Test {  public static void main(String[] args) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException {    // Trust own CA and all self-signed certs    SSLContext sslcontext = SSLContexts.custom()        .loadTrustMaterial(new File("D:\\cert\\trust.keystore"), "123456".toCharArray(),            new TrustSelfSignedStrategy())        .loadKeyMaterial(new File("D:\\cert\\me.keystore"), "123456".toCharArray(), "123456".toCharArray()).build();    // Allow TLSv1 protocol only    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(        sslcontext,        new String[] { "TLSv1" },        null,        SSLConnectionSocketFactory.getDefaultHostnameVerifier());    CloseableHttpClient httpclient = HttpClients.custom()        .setSSLSocketFactory(sslsf)        .build();    try {      HttpGet httpget = new HttpGet("https://helloworld.com:8443/hello/testget.json");      System.out.println("Executing request " + httpget.getRequestLine());      CloseableHttpResponse response = httpclient.execute(httpget);      try {        HttpEntity entity = response.getEntity();        System.out.println("----------------------------------------");        System.out.println(response.getStatusLine());        System.out.println(EntityUtils.toString(entity));        EntityUtils.consume(entity);      } finally {        response.close();      }    } finally {      httpclient.close();    }  }//    HttpPost httpPost = new HttpPost("http://targethost/login");//    List <NameValuePair> nvps = new ArrayList <NameValuePair>();//    nvps.add(new BasicNameValuePair("username", "vip"));//    nvps.add(new BasicNameValuePair("password", "secret"));//    httpPost.setEntity(new UrlEncodedFormEntity(nvps));//    CloseableHttpResponse response2 = httpclient.execute(httpPost);////    try {//      System.out.println(response2.getStatusLine());//      HttpEntity entity2 = response2.getEntity();//      // do something useful with the response body//      // and ensure it is fully consumed//      EntityUtils.consume(entity2);//    } finally {//      response2.close();//    }}

说明:如果自己的私钥库中有超过一个可选证书,系统会默认选择第一个。若受信任证书库中有超过一个证书,会遍历证书直到找到第一个匹配的。

参见http://stackoverflow.com/questions/6370745/can-we-load-multiple-certificates-keys-in-a-key-store