1、准备工作
A、域名绑定
在hosts文件末尾追加
127.0.0.1 www.zlex.org
B、证书导入
浏览器导入自签名证书文件zlex.cer
C、服务器配置
配置SSL/TLS 单向认证
<Connector
port="443"
SSLEnabled="true"
clientAuth="false"
maxThreads="150"
protocol="HTTP/1.1"
scheme="https"
sslProtocol="TLS"
keystoreFile="conf/zlex.keystore"
keystorePass="123456"/>
为使得HTTPS协议配置生效,我们需要将密钥库文件参数keystoreFile指向密钥库文件,并设定密钥库密钥参数keystorePass,密钥库类型参数keystoreType默认值"JKS"。
如果不显示配置信任库参数,信任库文件参数truststoreFile默认指向密钥库文件,信任库密码
参数truststorePass默认指向密钥库密码,信任库类型参数truststoreType默认值"JKS"。
客户端验证参数clientAuth,默认值"false"。构建双向认证服务时需要设置为"true",并修改密钥库参数和信任库参数。
2、服务验证
<%@ page languange="java" contentType="text/html;charset=UTF-8"%>
<%@ page import="java.util.Enumeration" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>zlex.org</title>
</head>
<body>
<p>request属性信息</p>
<pre>
<%
for(Enumeration en = request.getAttributeNames();en.hasMoreElements();) {
String name = (String) en.nextElement();
out.println(name);
out.println(" = " + request.getAttribute(name));
out.println();
}
%>
</pre>
</body>
</html>
javax.servlet.request.ssl_session:当前SSL/TLS协议的会话ID。
javax.servlet.request.key_size:当前加密算法所使用的密钥长度。
javax.servlet.request.cipher_suite:当前SSL/TLS协议所使用的加密套件。
3、代码验证
单向认证https
/**
* 2009-5-20
*/
package org.zlex.chapter11_1;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
/**
* HTTPS组件
*
* @author 梁栋
* @version 1.0
*/
public abstract class HTTPSCoder {
/**
* 协议
*/
public static final String PROTOCOL = "TLS";
/**
* 获得KeyStore
*
* @param keyStorePath
* 密钥库路径
* @param password
* 密码
* @return KeyStore 密钥库
* @throws Exception
*/
private static KeyStore getKeyStore(String keyStorePath, String password)
throws Exception {
// 实例化密钥库
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
// 获得密钥库文件流
FileInputStream is = new FileInputStream(keyStorePath);
// 加载密钥库
ks.load(is, password.toCharArray());
// 关闭密钥库文件流
is.close();
return ks;
}
/**
* 获得SSLSocektFactory
*
* @param password
* 密码
* @param keyStorePath
* 密钥库路径
* @param trustStorePath
* 信任库路径
* @return SSLSocketFactory
* @throws Exception
*/
private static SSLSocketFactory getSSLSocketFactory(String password,
String keyStorePath, String trustStorePath) throws Exception {
// 实例化密钥库
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
// 获得密钥库
KeyStore keyStore = getKeyStore(keyStorePath, password);
// 初始化密钥工厂
keyManagerFactory.init(keyStore, password.toCharArray());
// 实例化信任库
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// 获得信任库
KeyStore trustStore = getKeyStore(trustStorePath, password);
// 初始化信任库
trustManagerFactory.init(trustStore);
// 实例化SSL上下文
SSLContext ctx = SSLContext.getInstance(PROTOCOL);
// 初始化SSL上下文
ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
.getTrustManagers(), new SecureRandom());
// 获得SSLSocketFactory
return ctx.getSocketFactory();
}
/**
* 为HttpsURLConnection配置SSLSocketFactory
*
* @param conn
* HttpsURLConnection
* @param password
* 密码
* @param keyStorePath
* 密钥库路径
* @param trustKeyStorePath
* 信任库路径
* @throws Exception
*/
public static void configSSLSocketFactory(HttpsURLConnection conn,
String password, String keyStorePath, String trustKeyStorePath)
throws Exception {
// 获得SSLSocketFactory
SSLSocketFactory sslSocketFactory = getSSLSocketFactory(password,
keyStorePath, trustKeyStorePath);
// 设置SSLSocketFactory
conn.setSSLSocketFactory(sslSocketFactory);
}
}
单向认证示例
/**
* 2009-5-20
*/
package org.zlex.chapter11_1;
import static org.junit.Assert.*;
import java.io.DataInputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import org.junit.Test;
/**
* HTTPS测试
*
* @author 梁栋
* @version 1.0
*/
public class HTTPSCoderTest {
/**
* 密钥库/信任库密码
*/
private String password = "123456";
/**
* 密钥库文件路径
*/
private String keyStorePath = "d:/zlex.keystore";
/**
* 信任库文件路径
*/
private String trustStorePath = "d:/zlex.keystore";
/**
* 访问地址
*/
private String httpsUrl = "https://www.zlex.org/ssl/";
/**
* HTTPS验证
*
* @throws Exception
*/
@Test
public void test() throws Exception {
// 建立HTTPS链接
URL url = new URL(httpsUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// conn.setRequestMethod(method);
// 打开输入输出流
conn.setDoInput(true);
// conn.setDoOutput(true);
// 为HttpsURLConnection配置SSLSocketFactory
HTTPSCoder.configSSLSocketFactory(conn, password, keyStorePath,
trustStorePath);
// 鉴别内容长度
int length = conn.getContentLength();
byte[] data = null;
// 如果内容长度为-1,则放弃解析
if (length != -1) {
DataInputStream dis = new DataInputStream(conn.getInputStream());
data = new byte[length];
dis.readFully(data);
dis.close();
System.err.println(new String(data));
}
conn.disconnect();
// 验证
assertNotNull(data);
}
}