当需要使用安全的连接即HTTPS连接时,需配置SslHandler到ChannelPipeline,SslHandler无需另外写出,调用NETTY封装的即可,传入的SSLEngine在下面生成
package com.lin.socket.ssl;
import java.security.KeyStore;
import java.security.Security;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.apache.log4j.Logger;
/****************************************************************************
* com.lin.socket.ssl HttpSslContextFactory.java Created on 2012-9-11
*
* @Author: linfenliang
* @Description:SSL服务器端认证
* @Version: 1.0
***************************************************************************/
public class HttpSslContextFactory {
private static final Logger LOGGER = Logger.getLogger(HttpSslContextFactory.class);
private static final String PROTOCOL = "SSLv3";
/**针对于服务器端配置*/
private static SSLContext SSLCONTEXT = null;
static {
// 采用的加密算法
String algorithm = Security
.getProperty("ssl.KeyManagerFactory.algorithm");
if (algorithm == null) {
algorithm = "SunX509";
}
SSLContext serverContext = null;
try {
//访问Java密钥库,JKS是keytool创建的Java密钥库,保存密钥。
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(HttpsKeyStore.getKeyStoreStream(), HttpsKeyStore.getKeyStorePassword());
//创建用于管理JKS密钥库的密钥管理器。
KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
kmf.init(ks, HttpsKeyStore.getCertificatePassword());
//构造SSL环境,指定SSL版本为3.0,也可以使用TLSv1,但是SSLv3更加常用。
serverContext = SSLContext.getInstance(PROTOCOL);
//初始化SSL环境。第二个参数是告诉JSSE使用的可信任证书的来源,设置为null是从javax.net.ssl.trustStore中获得证书。第三个参数是JSSE生成的随机数,这个参数将影响系统的安全性,设置为null是个好选择,可以保证JSSE的安全性。
serverContext.init(kmf.getKeyManagers(), null, null);
} catch (Exception e) {
LOGGER.error("初始化客户端SSL失败", e);
throw new Error("Failed to initialize the server SSLContext", e);
}
SSLCONTEXT = serverContext;
}
/**
* 获取SSLContext实例
*
* @author linfenliang
* @date 2012-9-11
* @version V1.0.0
* @return
* SSLContext
*/
public static SSLContext getServerContext() {
return SSLCONTEXT ;
}
}
以上类即为配置的生产SSLContext的工厂,我们已经将我们生成的安全密钥以流的方式加载进KeyStore中了,密码是以CharArray的方式加载的,获取密钥和密码的方法在类HttpsKeyStore中,其主要功能方法如下:
/**
* 读取密钥
*
* @author linfenliang
* @date 2012-9-11
* @version V1.0.0
* @return InputStream
*/
public static InputStream getKeyStoreStream() {
InputStream inStream = null;
try {
inStream = new FileInputStream(Constants.KEYSTORE_PATH);
} catch (FileNotFoundException e) {
LOGGER.error("读取密钥文件失败", e);
}
return inStream;
}
/**
* 获取安全证书密码 (用于创建KeyManagerFactory)
*
* @author linfenliang
* @date 2012-9-11
* @version V1.0.0
* @return char[]
*/
public static char[] getCertificatePassword() {
return Constants.CERTIFICATEPASSWORD.toCharArray();
}
/**
* 获取密钥密码(证书别名密码) (用于创建KeyStore)
*
* @author linfenliang
* @date 2012-9-11
* @version V1.0.0
* @return char[]
*/
public static char[] getKeyStorePassword() {
return Constants.KEYSTOREPASSWORD.toCharArray();
}
消息的处理
// 判断消息类型,解析 消息
Object msg = e.getMessage();
HttpRequest request = (HttpRequest) e.getMessage();
// //数据提交方式验证
// if (request.getMethod() != HttpMethod.GET) {
// sendError(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED);
// return;
// }
String uri = request.getUri();
uri = URLDecoder.decode(uri, Constants.UTF8ENCODER);
ChannelBuffer buffer=new DynamicChannelBuffer(1024);
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
log.info(msg);
buffer.writeBytes(("测试SSL").getBytes());
response.setContent(buffer);
response.setHeader("Content-Type", "text/html; charset=UTF-8");
response.setHeader("Content-Length", response.getContent().writerIndex());
Channel ch = ctx.getChannel();
ch.write(response);
ch.close().awaitUninterruptibly();