资讯专栏INFORMATION COLUMN

Netty使用JSSE实现SSLSocket通信

DTeam / 1148人阅读

摘要:上文讲了如何使用生成的签名证书进行加密通信,结果客户端告诉我他们用的版本没有类,并且由于一些交易的原因还不能更新没有你总有吧,来吧。

上文讲了netty如何使用openssl生成的签名证书进行加密通信,结果客户端告诉我他们用的netty版本没有SslContextBuilder类,并且由于一些PY交易的原因还不能更新netty....

SslContextBuilder没有java你总有吧,来吧。

一、老规矩,创建key 1.创建客户端和服务端的keystore文件

随便找个文件夹就行,打开命令行输入

</>复制代码

  1. keytool -genkey -alias sslserver -keystore sslserverkeys
  2. keytool -genkey -alias sslclient -keystore sslclientkeys
2.将keystore导出证书格式

</>复制代码

  1. keytool -export -alias sslserver -keystore sslserverkeys -file sslserver.cer
  2. keytool -export -alias sslclient -keystore sslclientkeys -file sslclient.cer
3.将客户端证书导入到服务器端信任的 keystore 里,将服务器端证书导入到客户端信任的 keystore 里。

</>复制代码

  1. keytool -import -alias sslclient -keystore sslservertrust -file sslclient.cer
  2. keytool -import -alias sslserver -keystore sslclienttrust -file sslserver.cer

最后得到有用的文件分别为
服务端:sslserverkeys、sslservertrust
客户端:sslclientkeys、sslclienttrust

二、服务器端代码 (git) 服务器key工厂类 SecureChatSslContextFactory.java

</>复制代码

  1. public class SecureChatSslContextFactory {
  2. private static final String PROTOCOL = "SSL";
  3. private static final SSLContext SERVER_CONTEXT;
  4. private static String SERVER_KEY_STORE = ".sslsslserverkeys";
  5. private static String SERVER_TRUST_KEY_STORE = ".sslsslservertrust";
  6. private static String SERVER_KEY_STORE_PASSWORD = "123123123";
  7. private static String SERVER_TRUST_KEY_STORE_PASSWORD = "123123123";
  8. static {
  9. String algorithm = SystemPropertyUtil.get("ssl.KeyManagerFactory.algorithm");
  10. if (algorithm == null) {
  11. algorithm = "SunX509";
  12. }
  13. SSLContext serverContext;
  14. try {
  15. KeyStore ks = KeyStore.getInstance("JKS");
  16. ks.load(new FileInputStream(SERVER_KEY_STORE), SERVER_KEY_STORE_PASSWORD.toCharArray());
  17. KeyStore tks = KeyStore.getInstance("JKS");
  18. tks.load(new FileInputStream(SERVER_TRUST_KEY_STORE), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
  19. KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
  20. TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
  21. kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
  22. tmf.init(tks);
  23. serverContext = SSLContext.getInstance(PROTOCOL);
  24. serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  25. } catch (Exception e) {
  26. throw new Error(e);
  27. }
  28. SERVER_CONTEXT = serverContext;
  29. }
  30. public static SSLContext getServerContext() {
  31. return SERVER_CONTEXT;
  32. }
  33. }
Main.java

</>复制代码

  1. public class Main {
  2. private static final int m_port = 23333;
  3. public void run() throws InterruptedException {
  4. EventLoopGroup bossGroup = new NioEventLoopGroup(1);
  5. EventLoopGroup workerGroup = new NioEventLoopGroup();
  6. try {
  7. ServerBootstrap b = new ServerBootstrap();
  8. b.group(bossGroup, workerGroup)
  9. .channel(NioServerSocketChannel.class)
  10. .childHandler(new Initializer());
  11. System.out.println("启动了,端口:" + m_port);
  12. ChannelFuture f = b.bind(m_port).sync();
  13. f.channel().closeFuture().sync();
  14. } finally {
  15. bossGroup.shutdownGracefully();
  16. workerGroup.shutdownGracefully();
  17. System.out.println("关闭了");
  18. }
  19. }
  20. public static void main(String[] args) throws Exception {
  21. new Main().run();
  22. }
  23. }
Initializer.java

</>复制代码

  1. public class Initializer extends ChannelInitializer {
  2. @Override
  3. public void initChannel(SocketChannel ch) throws Exception {
  4. ChannelPipeline pipeline = ch.pipeline();
  5. SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
  6. engine.setUseClientMode(false);
  7. engine.setNeedClientAuth(true);
  8. pipeline.addLast("ssl", new SslHandler(engine));
  9. pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
  10. pipeline.addLast(new StringDecoder());
  11. pipeline.addLast(new StringEncoder());
  12. pipeline.addLast(new Handler());
  13. }
  14. }
Handler.java

</>复制代码

  1. public class Handler extends SimpleChannelInboundHandler {
  2. @Override
  3. public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
  4. Channel incoming = ctx.channel();
  5. ctx.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入
  6. ");
  7. }
  8. @Override
  9. protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
  10. Channel incoming = ctx.channel();
  11. System.out.println("收到" + incoming.id() + "消息:" + s);
  12. }
  13. @Override
  14. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  15. Channel incoming = ctx.channel();
  16. System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "在线");
  17. }
  18. @Override
  19. public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
  20. Channel incoming = ctx.channel();
  21. ctx.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 离开
  22. ");
  23. }
  24. @Override
  25. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  26. Channel incoming = ctx.channel();
  27. System.out.println(incoming.remoteAddress() + "掉线");
  28. }
  29. @Override
  30. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  31. Channel incoming = ctx.channel();
  32. System.out.println(incoming.remoteAddress() + "异常");
  33. // 当出现异常就关闭连接
  34. cause.printStackTrace();
  35. ctx.close();
  36. }
  37. }
三、客户端代码(git) SecureChatSslContextFactory.java

</>复制代码

  1. public class SecureChatSslContextFactory {
  2. private static final String PROTOCOL = "SSL";
  3. private static final SSLContext CLIENT_CONTEXT;
  4. private static String CLIENT_KEY_STORE = ".sslsslclientkeys";
  5. private static String CLIENT_TRUST_KEY_STORE = ".sslsslclienttrust";
  6. private static String CLIENT_KEY_STORE_PASSWORD = "321321321";
  7. private static String CLIENT_TRUST_KEY_STORE_PASSWORD = "321321321";
  8. static {
  9. String algorithm = SystemPropertyUtil.get("ssl.KeyManagerFactory.algorithm");
  10. if (algorithm == null) {
  11. algorithm = "SunX509";
  12. }
  13. SSLContext clientContext;
  14. try {
  15. KeyStore ks2 = KeyStore.getInstance("JKS");
  16. ks2.load(new FileInputStream(CLIENT_KEY_STORE), CLIENT_KEY_STORE_PASSWORD.toCharArray());
  17. KeyStore tks2 = KeyStore.getInstance("JKS");
  18. tks2.load(new FileInputStream(CLIENT_TRUST_KEY_STORE), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
  19. KeyManagerFactory kmf2 = KeyManagerFactory.getInstance(algorithm);
  20. TrustManagerFactory tmf2 = TrustManagerFactory.getInstance("SunX509");
  21. kmf2.init(ks2, CLIENT_KEY_STORE_PASSWORD.toCharArray());
  22. tmf2.init(tks2);
  23. clientContext = SSLContext.getInstance(PROTOCOL);
  24. clientContext.init(kmf2.getKeyManagers(), tmf2.getTrustManagers(), null);
  25. } catch (Exception e) {
  26. throw new Error(e);
  27. }
  28. CLIENT_CONTEXT = clientContext;
  29. }
  30. public static SSLContext getClientContext() {
  31. return CLIENT_CONTEXT;
  32. }
Main.java

</>复制代码

  1. public class Main {
  2. private static String m_host = "127.0.0.1";
  3. private static int m_prot = 23333;
  4. public static void main(String[] args) throws Exception {
  5. new Main().run();
  6. }
  7. public void run() throws Exception {
  8. EventLoopGroup group = new NioEventLoopGroup();
  9. try {
  10. Bootstrap bt = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new Initializer());
  11. Channel channel = bt.connect(m_host, m_prot).sync().channel();
  12. BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  13. while (true) {
  14. channel.writeAndFlush(in.readLine() + "
  15. ");
  16. }
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. } finally {
  20. group.shutdownGracefully();
  21. }
  22. }
  23. }
Initializer.java

</>复制代码

  1. public class Initializer extends ChannelInitializer{
  2. @Override
  3. public void initChannel(SocketChannel ch) throws Exception {
  4. ChannelPipeline pipeline = ch.pipeline();
  5. SSLEngine engine = SecureChatSslContextFactory.getClientContext().createSSLEngine();
  6. engine.setUseClientMode(true);
  7. pipeline.addLast("ssl", new SslHandler(engine));
  8. pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
  9. pipeline.addLast(new StringDecoder());
  10. pipeline.addLast(new StringEncoder());
  11. pipeline.addLast(new Handler());
  12. }
  13. }
Handler.java

</>复制代码

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67276.html

相关文章

  • SSLSocket

    摘要:定义扩展并提供使用或协议的安全套接字。它也是基于正常的流套接字,但是在网络传输协议如上添加了安全保护层。 SSLSocket定义 SSLSocket扩展Socket并提供使用SSL或TLS协议的安全套接字。它也是基于正常的流套接字,但是在网络传输协议(如TCP)上添加了安全保护层。 SSLSocket相关类 类 功能描述 SSLContext 该类的实例表示安全套接字协议的实...

    ConardLi 评论0 收藏0
  • Apple APNS http2 Provider 开发 使用 okHttp

    摘要:前言升级了后台推送接口,使用协议,提高了的最大大小,本文介绍新版实现方法基于框架框架不要使用的类直接发送请求,因为底层虽然使用了,可以设置和,但是超过,链接还是会断开,而官方建议保持长链接所以最好自建长链接,使用底层的类来直接发送请求,并通 前言 Apple 升级了后台推送接口,使用 http2 协议,提高了 payload 的最大大小(4k),本文介绍新版 APNS 实现方法 基于 ...

    widuu 评论0 收藏0
  • 慕课网_《Netty入门之WebSocket初体验》学习总结

    时间:2018年04月11日星期三 说明:本文部分内容均来自慕课网。@慕课网:https://www.imooc.com 教学源码:https://github.com/zccodere/s... 学习源码:https://github.com/zccodere/s... 第一章:课程介绍 1-1 课程介绍 什么是Netty 高性能、事件驱动、异步非阻塞的IO Java开源框架 基于NIO的客户...

    Noodles 评论0 收藏0
  • 【Java猫说】SSM整合Netty5.0详细说明

    摘要:而我们项目在实测时也是将项目发布到测试服务器,通过模拟工具进行测试连接,当数据格式正常,且业务数据正常,服务器就会对指令执行对应的操作。 阅读本文约5.5分钟 最近又有粉丝加Q群讨论netty整合SSM项目的方式等,我在这里抽了休息日的时候整理一下,一步一步的记录,注意的是,本案例仅实现了用netty整合SSM后与单片机等类TCP应用通信。 SSM + Netty项目结合思路 对于N...

    dingding199389 评论0 收藏0

发表评论

0条评论

DTeam

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<