IILeeのBlog

IILeeのBlog

Netty 的 WebSocket 客户端通过 SSL 连接服务器

938
2019-06-15
Netty 的 WebSocket 客户端通过 SSL 连接服务器

生成SSL证书

  1. 本地测试
    • 因为是测试,直接使用jdk自带的keytool工具生成自签名证书(注:自签名证书是不被浏览器认可的,只能用于测试)
    • 打开cmd
    • 输入命令(复制啊):keytool -genkey -keysize 2048 -validity 365 -keyalg RSA -keypass netty123 -storepass netty123 -keystore wss.jks
  2. 阿里云测试
    • 通过域名可取得免费证书(百度)

在ChannelPipeline添加SslHandler

首先写个工具类:SslUtil配置SSLContext

/**
 * @author chihiro
 * @version V1.0
 * @date 2019-06-15 09:00:00
 */
public static SSLContext createSSLContext(String type ,String path ,String password) throws Exception {
	// 证书类型"JKS、PKCS12"    
		KeyStore ks = KeyStore.getInstance(type); 
	// 证书存放地址
	    InputStream ksInputStream = new FileInputStream(path); 
	    ks.load(ksInputStream, password.toCharArray());
	//KeyManagerFactory充当基于密钥内容源的密钥管理器的工厂。
	//getDefaultAlgorithm:获取默认的 
	    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());KeyManagerFactory 算法名称。
	    kmf.init(ks, password.toCharArray());
	//SSLContext的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。
	    SSLContext sslContext = SSLContext.getInstance("TLS");
	    sslContext.init(kmf.getKeyManagers(), null, null);
	    return sslContext;
}

在ChannelInitialize的子类里面加入SSL

/**
 * @author chihiro
 * @version V1.0
 * @date 2019-06-15 09:00:00
 */
public class MyPipeline extends ChannelInitializer<SocketChannel> {
    
	@Override
    public void initChannel(SocketChannel ch) throws Exception {
        //阿里云证书与此处配置不同,类型为PKCS12    
        SSLContext sslContext = SslUtil.createSSLContext("JKS","D://wss.jks","netty123");
        //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
        SSLEngine engine = sslContext.createSSLEngine(); 
        engine.setUseClientMode(false); 
        //SslHandler应当放在首位
        ch.pipeline().addLast(new SslHandler(engine));
        ch.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));    
        ch.pipeline().addLast("http-codec", new HttpServerCodec());            
        ch.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));  
        ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());    
        ch.pipeline().addLast(new AcceptorIdleStateTrigger());    
        ch.pipeline().addLast("handler", new WebSocketHandler());            
        }
}

JS文件的URL

var url = "wss://localhost:8000/ws";

注:阿里云证书不可加【www.】前缀

/ws后缀属于自己定义的,具体定义请查看自己项目中的配置类

运行

  • 运行服务端,在浏览器地址栏输入https://localhost:8000/ 浏览器会提示这是不安全的连接(浏览器不信任自签名证书,如果有域名可以自己申请一个证书,网上有免费测试版的证书),添加例外信任,再在html页面上右键获得它的本地路径 在浏览器中运行。
  • 连接成功。