netty ssl 服务器

一、证书

(本文只介绍windows版,其他系统只供参考)

1.生成ca证书

  • 下载 openssl 并安装 未编译 编译好

  • openssl/bin目录下打开命令行,输入

openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf

在本目录得到 ca.key 和 ca.crt 文件

2.生成服务端和客户端私钥

  • 命令行输入

openssl genrsa -des3 -out server.key 1024
openssl genrsa -des3 -out client.key 1024

密码自己设定,好几个密码,别弄乱了就好,分不清的话都设成一样的

3.根据 key 生成 csr 文件

openssl req -new -key server.key -out server.csr -config openssl.cnf
openssl req -new -key client.key -out client.csr -config openssl.cnf

4.根据 ca 证书 server.csr 和 client.csr 生成 x509 证书

openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

5.将 key 文件进行 PKCS#8 编码

openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt

最后得到有用的文件分别为
服务器端: ca.crt、server.crt、pkcs8_server.key
客户端端: ca.crt、client.crt、pkcs8_client.key

二、服务器端代码

Main.java

public class Main {
    private static final int m_port = 23333;

    public void run() throws Exception {
        File certChainFile = new File(".\\ssl\\server.crt");
        File keyFile = new File(".\\ssl\\pkcs8_server.key");
        File rootFile = new File(".\\ssl\\ca.crt");
        SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile).trustManager(rootFile).clientAuth(ClientAuth.REQUIRE).build();
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new Initializer(sslCtx));
            ChannelFuture f = b.bind(m_port).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws Exception {
        new Main().run();
    }
}

Initializer.java

public class Initializer extends ChannelInitializer {
    private final SslContext sslCtx;
    public Initializer(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new Handler());
    }
}

Handler.java

public class Handler extends SimpleChannelInboundHandler {

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        ctx.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入\n");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("收到消息" + s)
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println(incoming.remoteAddress() + "在线");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        ctx.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 离开\n");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println(incoming.remoteAddress() + "掉线");
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println(incoming.remoteAddress() + "异常");
        // 当出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
    }

三、客户端代码

Main.java

public class Main {
    private static String m_host = "127.0.0.1";
    private static int m_prot = 23333;

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    public void run() throws Exception {
        File certChainFile = new File(".\\ssl\\client.crt");
        File keyFile = new File(".\\ssl\\pkcs8_client.key");
        File rootFile = new File(".\\ssl\\ca.crt"); 
        final SslContext sslCtx = SslContextBuilder.forClient().keyManager(certChainFile, keyFile).trustManager(rootFile).build();
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).handler(new Initializer(sslCtx));
            Channel ch = b.connect(m_host, m_prot).sync().channel();
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                ch.writeAndFlush(in.readLine() + "\r\n");
            }
        } finally {
            group.shutdownGracefully();
        }
    }
}

Initializer.java

public class Initializer extends ChannelInitializer{
    private final SslContext sslCtx;
    public Initializer(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));
        pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
        pipeline.addLast(new StringDecoder());
        pipeline.addLast(new StringEncoder());
        pipeline.addLast(new Handler());
    }
}

Handler.java

public class Handler extends SimpleChannelInboundHandler{
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        System.out.println("收到:" + s);
    }
}

你可能感兴趣的:(openssl,ssh,netty,java)