netty 实现https服务器
来源:互联网 发布:返利商城APP源码 编辑:程序博客网 时间:2024/05/19 18:12
0 概述
netty 通过JDK的SSLEngine,以SslHandler的方式提供对SSL/TLS 安全传输的支持,极大的简化了开发工作。本文主要讲述如何使用netty实现简单的https服务器。
1 SSL单向认证
所谓的单向认证,即客户端只验证服务端的合法性,服务端不会验证客户端。
单向认证过程的总结如下:
1.SSL客户端(浏览器)向服务端传送客户端 SSL协议的版本号、支持的加密算法种类、产生的随机数,以及其他可选信息。
2.服务端返回握手应答,向客户端传送确认SSL协议的版本号、加密算法种类、随机数以及其他信息。
3.服务端向客户端发送自己的证书,这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等
4.客户端对服务端的证书进行认证,服务端的合法性校验包括:证书是否过期、发行服务器证书CA是否可靠、发行者证书的公钥能否解开服务器证书的“发行者数字签名”等
5.客户端随机产生一个用于后续通信的对称密钥,然后用服务端的公钥加密传输给服务端,通知服务端客户端的握手结束。
6.服务端解密获取客户端的对称密钥,同时通知客户端服务端的握手结束。
7.SSL的握手部分结束,SSL安全通道建立,客户端和服务端开始使用相同的对称密钥对数据进行加密,然后通过socket进行传输。
2 具体实现
利用JDK的keytool 工具,生成服务端私钥和证书仓库。
执行如下命令:
keytool -genkey -keysize 2048 -validity 365 -keyalg RSA -dname “CN=localhost” -keypass hsc123 -storepass hsc123 -keystore local.jks
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.codec.http.HttpServerCodec;import io.netty.handler.ssl.SslHandler;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLEngine;/** * Created by apple on 17/10/21. */public class HttpsServer { public static void start(final int port) throws Exception { EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); try { serverBootstrap.channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .group(boss, worker) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { SSLEngine sslEngine = SSLContextFactory.getSslContext().createSSLEngine(); sslEngine.setUseClientMode(false); ch.pipeline().addLast(new SslHandler(sslEngine)); ch.pipeline().addLast("http-decoder", new HttpServerCodec()); ch.pipeline().addLast(new HttpsSeverHandler()); } }); ChannelFuture future = serverBootstrap.bind(port).sync(); future.channel().closeFuture().sync(); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } public static void main(String[] args) throws Exception { start(7000); }}
import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import java.io.FileInputStream;import java.security.KeyStore;import java.security.KeyStoreException;/** * Created by apple on 17/10/21. */public class SSLContextFactory { public static SSLContext getSslContext() throws Exception { char[] passArray = "hsc123".toCharArray(); SSLContext sslContext = SSLContext.getInstance("TLSv1"); KeyStore ks = KeyStore.getInstance("JKS"); //加载keytool 生成的文件 FileInputStream inputStream = new FileInputStream("/Users/apple/local.jks"); ks.load(inputStream, passArray); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, passArray); sslContext.init(kmf.getKeyManagers(), null, null); inputStream.close(); return sslContext; }
import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.handler.codec.http.*;/** * Created by apple on 17/10/21. */public class HttpsSeverHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof HttpRequest) { HttpRequest request = (HttpRequest) msg; boolean keepaLive = HttpUtil.isKeepAlive(request); System.out.println("method" + request.method()); System.out.println("uri" + request.uri()); FullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); httpResponse.content().writeBytes("https".getBytes()); httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=UTF-8"); httpResponse.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, httpResponse.content().readableBytes()); if (keepaLive) { httpResponse.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.writeAndFlush(httpResponse); } else { ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE); } } }}
3 测试
启动服务 输入https://127.0.0.1:7000
参考文献
[1] Netty 权威指南(第二版),李林峰著
- netty 实现https服务器
- netty实现http服务器
- 在Netty中支持https服务器
- netty 实现 服务器 客户端通信
- Netty实现简单HTTP服务器
- jetty https服务器实现
- libevent实现https服务器
- Tomcat服务器实现https
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- Netty-SocketIO实现服务器消息推送
- Play框架的Netty Http服务器实现
- Apache+OpenSSL实现证书服务器提供HTTPS
- 服务器(6)--Nginx实现HTTPS网站设置
- Netty实现带UI客户端服务器聊天功能
- Netty5用户手册之二:使用netty实现Discard服务器程序
- Netty实现服务器推Push(Android推送)
- 累
- bzoj2839 集合计数 (容斥原理+组合数)
- sslh使用
- L
- 反向生成符合正则表达式的字符串
- netty 实现https服务器
- Unity 制作小地图
- RecyeclerView的总结
- 《C语言程序设计》例2-3 2-5 2-6
- 欧拉函数打表
- 字符与字符串处理之getchar,gets,putchar,puts函数
- LA4080 Warfare And Logistics (dijkstra+最短路树)
- c++考试总结
- CCF CSP 权限查询 JAVA 201612-3