openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf
在本目錄獲得 ca.key 和 ca.crt 文件web
命令行輸入windows
openssl genrsa -des3 -out server.key 1024 openssl genrsa -des3 -out client.key 1024
密碼本身設定,好幾個密碼,別弄亂了就好,分不清的話都設成同樣的服務器
openssl req -new -key server.key -out server.csr -config openssl.cnf openssl req -new -key client.key -out client.csr -config openssl.cnf
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
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.keyide
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(); } }
public class Initializer extends ChannelInitializer<SocketChannel> { 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()); } }
public class Handler extends SimpleChannelInboundHandler<String> { @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(); }
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(); } } }
public class Initializer extends ChannelInitializer<SocketChannel>{ 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()); } }
public class Handler extends SimpleChannelInboundHandler<String>{ protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception { System.out.println("收到:" + s); } }