Tomcat容器https配置之单向认证
测试环境
Windows 7
IE 11
Intellij IDEA 2017
JDK 1.8.0_25
Tomcat 6.0.36
httpcore 4.4.6
httpclient 4.5.3
keytool:证书生成工具,在JDK 1.4以后的版本中都包含了这一工具,它的位置为<JAVA_HOME>\bin\keytool.exe
单向认证
-
生成服务端keystore
C:\Users\Administrator>keytool -genkeypair -alias server -keyalg RSA -keysize 1024 -keypass changeit -keystore d:/server -storepass changeit 您的名字与姓氏是什么? [Unknown]: localhost 您的组织单位名称是什么? [Unknown]: localhost 您的组织名称是什么? [Unknown]: localhost 您所在的城市或区域名称是什么? [Unknown]: hz 您所在的省/市/自治区名称是什么? [Unknown]: zj 该单位的双字母国家/地区代码是什么? [Unknown]: cn CN=localhost, OU=localhost, O=localhost, L=hz, ST=zj, C=cn是否正确? [否]: y
注意:keypass 和 storepass 要保持一致 如上例中的changeit
-
导出服务端证书
C:\Users\Administrator>keytool -exportcert -alias server -file d:/server.cer -keystore d:/server -storepass changeit
-
将服务端证书导入到客户端的环境中
C:\Users\Administrator>keytool -importcert -alias server -keystore %JAVA_HOME%\jre\lib\security\cacerts -storepass changeit -file d:/server.cer 所有者: CN=localhost, OU=localhost, O=localhost, L=hz, ST=zj, C=cn 发布者: CN=localhost, OU=localhost, O=localhost, L=hz, ST=zj, C=cn 序列号: 7ba673fa 有效期开始日期: Sun May 21 16:34:22 CST 2017, 截止日期: Sat Aug 19 16:34:22 CST 2017 证书指纹: MD5: F6:00:4B:9B:43:63:5A:26:20:4D:32:5B:70:FA:C4:71 SHA1: 25:EB:6A:06:FA:46:73:A7:AB:7E:C2:C3:A1:E2:3B:62:1C:A8:BF:24 SHA256: A2:DD:86:9F:22:69:2F:C2:D3:0C:36:93:6A:DB:E4:68:87:47:E1:10:C8: 4F:0C:9B:01:64:51:45:E6:BF:58:A4 签名算法名称: SHA256withRSA 版本: 3 扩展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: E3 04 36 1E 00 1C 77 34 29 2C AE BF CC FC 28 F5 ..6...w4),....(. 0010: D8 17 1C 17 .... ] ] 是否信任此证书? [否]: y 证书已添加到密钥库中
这一步可以不用执行,只要代码中设置不校验证书即可,但是这样不安全,不推荐。
-
配置Tomcat
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="D:/server" keystorePass="changeit"/>
-
测试
- 浏览器访问 https://localhost (提示警告 选择继续浏览即可)
- httpclient测试访问
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.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * Created by leafsunday on 2017/5/20 . */ public class HttpsTest { public static void main(String args[]) throws Exception{ CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).build(); HttpGet httpGet = new HttpGet("https://localhost"); CloseableHttpResponse response = httpClient.execute(httpGet); String httpStr = EntityUtils.toString(response.getEntity(), "utf-8"); System.out.println(httpStr); } /** * 创建SSL安全连接 * * @return */ private static SSLConnectionSocketFactory createSSLConnSocketFactory() throws Exception { SSLContext sslContext = SSLContextBuilder.create() /* //设置不校验服务端证书 不安全(不推荐) .loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }) */ .build(); return new SSLConnectionSocketFactory(sslContext /* //设置不校验hostname , new HostnameVerifier() { public boolean verify(String s, SSLSession sslSession) { return true; } } */ ); } }