https 的理解

了解https ,首先和http做一下区分 。http也就是超文本传输协议,也就是平常我们浏览网站使用的一种端口。http传输的数据都是未加密的,所以安全性不高,http占用的端口是80.


https,也称作超文本安全传输协议,使用443端口,它基于http之上通信,但是数据经过SSL/TSL进行加密,传输数据更为安全。


https工作原理如同对一份加密文件进行**,俩方的**的方式以及**出的内容相同,即成功匹配。

这里说一种jdk给tomcat配置https

1、生成服务器证书:

CMD进入JDK安装目录:cd c:/"Program Files"/java/jdk1.6.0_43/bin。输入命令:

keytool -genkey -v -alias tomcat -keyalg RSA -keystore F:/ssl/tomcat.keystore -validity 365

https 的理解

(参数说明:genkey生成方式,对称或者非对称。alias定义别名。F:/ssl/tomcat.keystore指定生成服务器证书库路径。validity证书有效期,365为一年

2、生成客户端证书:

keytool -genkey -v -alias clientkey -keyalg RSA -storetype PKCS12 -keystore F:/ssl/clientkey.p12

https 的理解https 的理解https 的理解

3、这里服务端跟客户端生成完证书,双向需要认证。首先,让服务器信任客户端证书:

由于不能直接将PKCS12格式的证书库导入,所以必须先把客户端证书导出为一个单独的CER文件。

keytool -export -alias clientkey -keystore F:/ssl/clientkey.p12 -storetype PKCS12 -storepass 123456 -rfc -file F:/ssl/clientkey.cer

https 的理解https 的理解

4、将客户端证书导入服务器证书库。(服务器信任客户端证书)

keytool -import -v -file f:/ssl/clientkey.cer -keystore f:/ssl/tomcat.keystore

https 的理解https 的理解https 的理解

5、客户端信任服务器证书:

keytool -keystore f:/ssl/tomcat.keystore -export -alias tomcat -file f:/ssl/tomcat.cer

https 的理解https 的理解https 的理解

导入后,本地安装证书。双击tomcat.cer根据提示安装。

6、配置tomcat种server.xml种8443端口。观察tomcat中端口配置:

<Connector executor="tomcatThreadPool"  port="8080" protocol="HTTP/1.1"   connectionTimeout="20000"  redirectPort="8443"/>

这里有配置redirectPort="8443" 。猜测这里如果添加了SSL/TLS证书后,利用http协议8080端口访问将自动重定向到8443端口。所以这里修改8443为TLS认证协议:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
      keystoreFile="F:/ssl/tomcat.keystore" keystorePass="123456"
  ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_ 
CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_C 
BC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RS 
A_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"
  />

参数说明:keystoreFile证书路径。keystorePass设置证书密码。ciphers设置这个参数,避免chrome浏览器由于安全机制过滤,提示“

服务器的瞬时 Diffie-Hellman 公共**过弱”。

7、配置工程web.xml,添加ssl认证,将http请求全部需要ssl认证:
<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
8、本地使用http://localhost:8443/测试访问。

这里补充一点,tomcat配置好后运行Post方法可能会有异常,原因是我们自己自制的证书服务器会不信任,代码中要忽略证书信任问题,这里要在建立连接Connection 之前加入
  1. trustAllHttpsCertificates();  
  2. HttpsURLConnection.setDefaultHostnameVerifier(hv); 
俩个方法,方法具体如下
static HostnameVerifier hv = new HostnameVerifier() { 
        public boolean verify(String urlHostName, SSLSession session) { 
            System.out.println("Warning: URL Host: " + urlHostName + " vs. " 
                               + session.getPeerHost()); 
            return true; 
        } 
    }; 
     
    private static void trustAllHttpsCertificates() throws Exception { 
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; 
        javax.net.ssl.TrustManager tm = new miTM(); 
        trustAllCerts[0] = tm; 
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext 
                .getInstance("SSL"); 
        sc.init(null, trustAllCerts, null); 
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc 
                .getSocketFactory()); 
    } 
 
    static class miTM implements javax.net.ssl.TrustManager, 
            javax.net.ssl.X509TrustManager { 
        public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
            return null; 
        } 
 
        public boolean isServerTrusted( 
                java.security.cert.X509Certificate[] certs) { 
            return true; 
        } 
 
        public boolean isClientTrusted( 
                java.security.cert.X509Certificate[] certs) { 
            return true; 
        } 
 
        public void checkServerTrusted( 
                java.security.cert.X509Certificate[] certs, String authType) 
                throws java.security.cert.CertificateException { 
            return; 
        } 
 
        public void checkClientTrusted( 
                java.security.cert.X509Certificate[] certs, String authType) 
                throws java.security.cert.CertificateException { 
            return; 
        } 
    }