一、证书准备

要使用ssl双向验证,就必须先要生成服务端和客户端的证书,并相互添加信任,具体流程如下(本人调试这个用例的时候,花了很多时间来验证证书是否正确,以及握手失败的原因,这里证书生成过程只要按流程走,本人能保证绝对没有问题)

现在打开cmd,在哪个目录下打开,证书就会放在哪个目录下:

第一步:   生成Netty服务端私钥和证书仓库命令

keytool -genkey -alias securechat -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass sNetty -storepass sNetty -keystore sChat.jks

  • -keysize 2048 密钥长度2048位(这个长度的密钥目前可认为无法被暴力破解)
  • -validity 365 证书有效期365天
  • -keyalg RSA 使用RSA非对称加密算法
  • -dname "CN=localhost" 设置Common Name为localhost
  • -keypass sNetty密钥的访问密码为sNetty
  • -storepass sNetty密钥库的访问密码为sNetty(其实这两个密码也可以设置一样,通常都设置一样,方便记)
  • -keystore sChat.jks 指定生成的密钥库文件为sChata.jks

第二步:生成Netty服务端自签名证书

keytool -export -alias securechat -keystore sChat.jks -storepass sNetty -file sChat.cer

第三步:生成客户端的密钥对和证书仓库,用于将服务端的证书保存到客户端的授信证书仓库中

    keytool -genkey -alias smcc -keysize 2048 -validity 365  -keyalg RSA -dname "CN=localhost" -keypass sNetty  -storepass sNetty -keystore cChat.jks

第四步:将Netty服务端证书导入到客户端的证书仓库中

keytool -import -trustcacerts -alias securechat -file sChat.cer -storepass sNetty -keystore cChat.jks

如果你只做单向认证,则到此就可以结束了,如果是双响认证,则还需继续往下走

第五步:生成客户端自签名证书

keytool -export -alias smcc -keystore cChat.jks -storepass sNetty -file cChat.cer

最后一步:将客户端的自签名证书导入到服务端的信任证书仓库中:

keytool -import -trustcacerts -alias smcc -file cChat.cer -storepass sNetty -keystore sChat.jks

到这里,证书就生成完毕了,我们就可以得到两个jks文件,一个是服务端的sChat.jks  ,一个是客户端的cChat.jks   ,这两个文件后面初始化sslCOntext的时候会用到

如果还想了解更多可以查看

http://dwj147258.iteye.com/blog/2339934

二、netty服务端

下面就直接贴代码了,首先是实例化SSLContext的类:

  1. package main.java.com.nionetty;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.security.KeyStore;
  5. import java.security.NoSuchAlgorithmException;
  6. import javax.net.ssl.KeyManager;
  7. import javax.net.ssl.KeyManagerFactory;
  8. import javax.net.ssl.SSLContext;
  9. import javax.net.ssl.TrustManager;
  10. import javax.net.ssl.TrustManagerFactory;
  11. import org.springframework.core.io.ClassPathResource;
  12. /**
  13. * 初始化sslcontext类
  14. *
  15. */
  16. public class ContextSSLFactory {
  17. private static final SSLContext SSL_CONTEXT_S ;
  18. private static final SSLContext SSL_CONTEXT_C ;
  19. static{
  20. SSLContext sslContext = null ;
  21. SSLContext sslContext2 = null ;
  22. try {
  23. sslContext = SSLContext.getInstance("SSLv3") ;
  24. sslContext2 = SSLContext.getInstance("SSLv3") ;
  25. } catch (NoSuchAlgorithmException e1) {
  26. e1.printStackTrace();
  27. }
  28. try{
  29. if(getKeyManagersServer() != null && getTrustManagersServer() != null ){
  30. sslContext.init(getKeyManagersServer(), getTrustManagersServer(), null);
  31. }
  32. if(getKeyManagersClient() != null && getTrustManagersClient() != null){
  33. sslContext2.init(getKeyManagersClient(), getTrustManagersClient(), null);
  34. }
  35. }catch(Exception e){
  36. e.printStackTrace() ;
  37. }
  38. sslContext.createSSLEngine().getSupportedCipherSuites() ;
  39. sslContext2.createSSLEngine().getSupportedCipherSuites() ;
  40. SSL_CONTEXT_S = sslContext ;
  41. SSL_CONTEXT_C = sslContext2 ;
  42. }
  43. public ContextSSLFactory(){
  44. }
  45. public static SSLContext getSslContext(){
  46. return SSL_CONTEXT_S ;
  47. }
  48. public static SSLContext getSslContext2(){
  49. return SSL_CONTEXT_C ;
  50. }
  51. private static TrustManager[] getTrustManagersServer(){
  52. FileInputStream is = null ;
  53. KeyStore ks = null ;
  54. TrustManagerFactory keyFac = null ;
  55. TrustManager[] kms = null ;
  56. try {
  57. // 获得KeyManagerFactory对象. 初始化位默认算法
  58. keyFac = TrustManagerFactory.getInstance("SunX509") ;
  59. is =new FileInputStream( (new ClassPathResource("main/java/conf/sChat.jks")).getFile() );
  60. ks = KeyStore.getInstance("JKS") ;
  61. String keyStorePass = "sNetty" ;
  62. ks.load(is , keyStorePass.toCharArray()) ;
  63. keyFac.init(ks) ;
  64. kms = keyFac.getTrustManagers() ;
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. }
  68. finally{
  69. if(is != null ){
  70. try {
  71. is.close() ;
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. }
  77. return kms ;
  78. }
  79. private static TrustManager[] getTrustManagersClient(){
  80. FileInputStream is = null ;
  81. KeyStore ks = null ;
  82. TrustManagerFactory keyFac = null ;
  83. TrustManager[] kms = null ;
  84. try {
  85. // 获得KeyManagerFactory对象. 初始化位默认算法
  86. keyFac = TrustManagerFactory.getInstance("SunX509") ;
  87. is =new FileInputStream( (new ClassPathResource("main/java/conf/cChat.jks")).getFile() );
  88. ks = KeyStore.getInstance("JKS") ;
  89. String keyStorePass = "sNetty" ;
  90. ks.load(is , keyStorePass.toCharArray()) ;
  91. keyFac.init(ks) ;
  92. kms = keyFac.getTrustManagers() ;
  93. } catch (Exception e) {
  94. e.printStackTrace();
  95. }
  96. finally{
  97. if(is != null ){
  98. try {
  99. is.close() ;
  100. } catch (IOException e) {
  101. e.printStackTrace();
  102. }
  103. }
  104. }
  105. return kms ;
  106. }
  107. private static KeyManager[] getKeyManagersServer(){
  108. FileInputStream is = null ;
  109. KeyStore ks = null ;
  110. KeyManagerFactory keyFac = null ;
  111. KeyManager[] kms = null ;
  112. try {
  113. // 获得KeyManagerFactory对象. 初始化位默认算法
  114. keyFac = KeyManagerFactory.getInstance("SunX509") ;
  115. is =new FileInputStream( (new ClassPathResource("main/java/conf/sChat.jks")).getFile() );
  116. ks = KeyStore.getInstance("JKS") ;
  117. String keyStorePass = "sNetty" ;
  118. ks.load(is , keyStorePass.toCharArray()) ;
  119. keyFac.init(ks, keyStorePass.toCharArray()) ;
  120. kms = keyFac.getKeyManagers() ;
  121. } catch (Exception e) {
  122. e.printStackTrace();
  123. }
  124. finally{
  125. if(is != null ){
  126. try {
  127. is.close() ;
  128. } catch (IOException e) {
  129. e.printStackTrace();
  130. }
  131. }
  132. }
  133. return kms ;
  134. }
  135. private static KeyManager[] getKeyManagersClient(){
  136. FileInputStream is = null ;
  137. KeyStore ks = null ;
  138. KeyManagerFactory keyFac = null ;
  139. KeyManager[] kms = null ;
  140. try {
  141. // 获得KeyManagerFactory对象. 初始化位默认算法
  142. keyFac = KeyManagerFactory.getInstance("SunX509") ;
  143. is =new FileInputStream( (new ClassPathResource("main/java/conf/cChat.jks")).getFile() );
  144. ks = KeyStore.getInstance("JKS") ;
  145. String keyStorePass = "sNetty" ;
  146. ks.load(is , keyStorePass.toCharArray()) ;
  147. keyFac.init(ks, keyStorePass.toCharArray()) ;
  148. kms = keyFac.getKeyManagers() ;
  149. } catch (Exception e) {
  150. e.printStackTrace();
  151. }
  152. finally{
  153. if(is != null ){
  154. try {
  155. is.close() ;
  156. } catch (IOException e) {
  157. e.printStackTrace();
  158. }
  159. }
  160. }
  161. return kms ;
  162. }
  163. }

服务端启动类:

  1. package main.java.com.nionetty;
  2. import javax.net.ssl.SSLEngine;
  3. import javax.print.attribute.standard.MediaSize.Engineering;
  4. import main.java.com.nettyTest.SecureChatServerHandler;
  5. import io.netty.bootstrap.ServerBootstrap;
  6. import io.netty.channel.ChannelHandlerContext;
  7. import io.netty.channel.ChannelInitializer;
  8. import io.netty.channel.ChannelOption;
  9. import io.netty.channel.ChannelPipeline;
  10. import io.netty.channel.EventLoopGroup;
  11. import io.netty.channel.nio.NioEventLoopGroup;
  12. import io.netty.channel.socket.SocketChannel;
  13. import io.netty.channel.socket.nio.NioServerSocketChannel;
  14. import io.netty.handler.logging.LogLevel;
  15. import io.netty.handler.logging.LoggingHandler;
  16. import io.netty.handler.ssl.SslHandler;
  17. import io.netty.handler.timeout.IdleState;
  18. import io.netty.handler.timeout.IdleStateEvent;
  19. import io.netty.handler.timeout.IdleStateHandler;
  20. public class NettySocketServer {
  21. private static SslHandler sslHandler = null ;
  22. private EventLoopGroup bossGroup = null ;
  23. private EventLoopGroup workerGroup = null ;
  24. public void start(){
  25. bossGroup = new NioEventLoopGroup() ;
  26. workerGroup = new NioEventLoopGroup() ;
  27. try{
  28. ServerBootstrap serverStrap = new ServerBootstrap() ;
  29. serverStrap.group(bossGroup , workerGroup)
  30. .channel(NioServerSocketChannel.class)
  31. .option(ChannelOption.SO_BACKLOG, 128)
  32. .option(ChannelOption.SO_KEEPALIVE, true)
  33. .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000 * 5 * 60)
  34. .handler(new LoggingHandler(LogLevel.DEBUG))
  35. .childHandler(new ChannelInitializer<SocketChannel>() {
  36. @Override
  37. protected void initChannel(SocketChannel socketChannel) throws Exception {
  38. ChannelPipeline pie = socketChannel.pipeline() ;
  39. pie.addLast("decoder" , new MyDecoder()) ;
  40. pie.addLast("encoder" , new MyEncoder()) ;
  41. pie.addLast("handler" , new NettySocketSSLHandler()) ;
  42. SSLEngine engine = ContextSSLFactory.getSslContext().createSSLEngine();
  43. engine.setUseClientMode(false);
  44. engine.setNeedClientAuth(true);
  45. pie.addFirst("ssl", new SslHandler(engine));
  46. }
  47. });
  48. serverStrap.bind(161616).sync() ;
  49. System.out.println("服务已开启");
  50. }catch(Exception e){
  51. e.printStackTrace() ;
  52. bossGroup.shutdownGracefully() ;
  53. workerGroup.shutdownGracefully() ;
  54. }
  55. }
  56. private SslHandler getSslHandler(){
  57. if(sslHandler == null ){
  58. SSLEngine sslEngine = ContextSSLFactory.getSslContext().createSSLEngine() ;
  59. sslEngine.setUseClientMode(false) ;
  60. //false为单向认证,true为双向认证
  61. sslEngine.setNeedClientAuth(true) ;
  62. sslHandler = new SslHandler(sslEngine);
  63. }
  64. return sslHandler ;
  65. }
  66. public static void main(String[] args) {
  67. new NettySocketServer().start() ;
  68. }
  69. }

编码器:

  1. package main.java.com.nionetty;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.handler.codec.MessageToByteEncoder;
  5. import java.nio.ByteBuffer;
  6. public class MyEncoder extends MessageToByteEncoder<ByteBuffer>{
  7. @Override
  8. protected void encode(ChannelHandlerContext ctx, ByteBuffer message,
  9. ByteBuf out) throws Exception {
  10. if(message==null){
  11. return;
  12. }
  13. if(message.hasArray()){
  14. byte[] msg =message.array();
  15. if(msg == null || msg.length <= 0){
  16. return;
  17. }
  18. out.writeBytes(msg) ;
  19. }
  20. }
  21. }

解码器:

  1. /*
  2. * Copyright (C) TD Tech<br>
  3. * All Rights Reserved.<br>
  4. *
  5. */
  6. package main.java.com.nionetty;
  7. import io.netty.buffer.ByteBuf;
  8. import io.netty.channel.ChannelHandlerContext;
  9. import io.netty.handler.codec.ByteToMessageDecoder;
  10. import java.nio.ByteBuffer;
  11. import java.util.List;
  12. /**
  13. * Create Date: 2014-11-4 下午02:42:21<br>
  14. * Create Author: lWX232692<br>
  15. * Description :
  16. */
  17. public class MyDecoder extends ByteToMessageDecoder {
  18. @Override
  19. protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
  20. List<Object> out) throws Exception {
  21. //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)
  22. if (buffer != null) {
  23. ByteBuffer msg = null;
  24. try {
  25. if(buffer.readableBytes() > 0 ){
  26. msg = ByteBuffer.allocate(buffer.readableBytes()) ;
  27. byte[] bb = new byte[buffer.readableBytes()] ;
  28. buffer.readBytes(bb) ;
  29. msg.put(bb);
  30. msg.flip();
  31. }
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. msg = null ;
  35. }
  36. if (msg != null) {
  37. out.add(msg);
  38. }
  39. }
  40. }
  41. }

业务实现类:

  1. package main.java.com.nionetty;
  2. import io.netty.channel.Channel;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.SimpleChannelInboundHandler;
  5. import io.netty.handler.ssl.SslHandler;
  6. import io.netty.util.concurrent.Future;
  7. import io.netty.util.concurrent.GenericFutureListener;
  8. import java.net.InetAddress;
  9. import java.nio.ByteBuffer;
  10. import java.util.Arrays;
  11. public class NettySocketSSLHandler extends SimpleChannelInboundHandler<ByteBuffer>{
  12. @Override
  13. public void channelActive(final ChannelHandlerContext ctx) throws Exception {
  14. // Once session is secured, send a greeting and register the channel to the global channel
  15. // list so the channel received the messages from others.
  16. ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(
  17. new GenericFutureListener<Future<Channel>>() {
  18. @Override
  19. public void operationComplete(Future<Channel> future) throws Exception {
  20. if(future.isSuccess()){
  21. System.out.println("握手成功");
  22. byte[] array = new byte[]{ (byte)7d,  04} ;
  23. ByteBuffer bu = ByteBuffer.wrap(array) ;
  24. ctx.channel().writeAndFlush(bu) ;
  25. }else{
  26. System.out.println("握手失败");
  27. }
  28. ctx.writeAndFlush(
  29. "Welcome to " + InetAddress.getLocalHost().getHostName() +
  30. " secure chat service!\n");
  31. ctx.writeAndFlush(
  32. "Your session is protected by " +
  33. ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite() +
  34. " cipher suite.\n");
  35. }
  36. });
  37. }
  38. @Override
  39. public void handlerAdded(ChannelHandlerContext ctx)
  40. throws Exception {
  41. System.out.println("服务端增加");
  42. }
  43. @Override
  44. public void handlerRemoved(ChannelHandlerContext ctx){
  45. System.out.println("移除:"+ctx.channel().remoteAddress());
  46. }
  47. @Override
  48. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  49. System.out.println("Unexpected exception from downstream.");
  50. ctx.close();
  51. }
  52. @Override
  53. public void messageReceived(ChannelHandlerContext ctx, ByteBuffer msg) throws Exception {
  54. System.out.println("服务端receive msg ");
  55. byte[] array = new byte[]{00, 01, 00, 00, 00, 06, 05, 03, (byte)7d, 00, 00, 07} ;
  56. ByteBuffer bu = ByteBuffer.wrap(array) ;
  57. ctx.channel().writeAndFlush(bu) ;
  58. }
  59. }

三、客户端

客户端实现类

  1. package main.java.com.nionetty.client;
  2. import java.net.InetSocketAddress;
  3. import java.net.SocketAddress;
  4. import javax.net.ssl.SSLEngine;
  5. import io.netty.bootstrap.Bootstrap;
  6. import io.netty.channel.Channel;
  7. import io.netty.channel.ChannelFuture;
  8. import io.netty.channel.ChannelInitializer;
  9. import io.netty.channel.ChannelOption;
  10. import io.netty.channel.ChannelPipeline;
  11. import io.netty.channel.EventLoopGroup;
  12. import io.netty.channel.nio.NioEventLoopGroup;
  13. import io.netty.channel.socket.SocketChannel;
  14. import io.netty.channel.socket.nio.NioSocketChannel;
  15. import io.netty.handler.ssl.SslHandler;
  16. import main.java.com.nionetty.ContextSSLFactory;
  17. import main.java.com.nionetty.MyDecoder;
  18. import main.java.com.nionetty.MyEncoder;
  19. public class NettySocketClient {
  20. private EventLoopGroup group ;
  21. private Channel channel = null ;
  22. public void connect(String ip , int port){
  23. group = new NioEventLoopGroup();
  24. try{
  25. Bootstrap strap = new Bootstrap();
  26. strap.group(group)
  27. .channel(NioSocketChannel.class)
  28. .option(ChannelOption.TCP_NODELAY, true)
  29. .option(ChannelOption.SO_KEEPALIVE , true)
  30. .handler(new ChannelInitializer<SocketChannel>() {
  31. @Override
  32. protected void initChannel(SocketChannel socketChannel) throws Exception {
  33. ChannelPipeline pieple = socketChannel.pipeline() ;
  34. pieple.addLast("decoder" , new MyClientDecoder()) ;
  35. pieple.addLast("encoder" , new MyClientEncoder()) ;
  36. pieple.addLast("handler" , new NettySocketSSLClientHandler()) ;
  37. SSLEngine engine = ContextSSLFactory.getSslContext2().createSSLEngine();
  38. engine.setUseClientMode(true);
  39. pieple.addFirst("ssl", new SslHandler(engine));
  40. }
  41. });
  42. SocketAddress address = new InetSocketAddress(ip, port);
  43. final ChannelFuture future = strap.connect(address).sync();
  44. channel = future.awaitUninterruptibly().channel();
  45. System.out.println("连接成功, channel =" + channel.remoteAddress());
  46. }catch(Exception e ){
  47. e.printStackTrace();
  48. group.shutdownGracefully() ;
  49. }finally{
  50. }
  51. }
  52. private static SslHandler sslHandlerClient = null ;
  53. public static SslHandler getSslHandler(){
  54. if(sslHandlerClient == null){
  55. SSLEngine sslEngine = ContextSSLFactory.getSslContext2().createSSLEngine() ;
  56. sslEngine.setUseClientMode(true) ;
  57. sslHandlerClient = new SslHandler(sslEngine);
  58. }
  59. return sslHandlerClient ;
  60. }
  61. public static void main(String[] args) {
  62. new NettySocketClient().connect("192.168.10.256", 161616) ;
  63. }
  64. }

编码器:

  1. package main.java.com.nionetty.client;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.handler.codec.MessageToByteEncoder;
  5. import java.nio.ByteBuffer;
  6. public class MyClientEncoder extends MessageToByteEncoder<ByteBuffer>{
  7. @Override
  8. protected void encode(ChannelHandlerContext ctx, ByteBuffer message,
  9. ByteBuf out) throws Exception {
  10. if(message==null){
  11. return;
  12. }
  13. if(message .hasArray()){
  14. byte[] msg =message.array();
  15. if(msg == null || msg.length <= 0){
  16. return;
  17. }
  18. out.writeBytes(msg);
  19. }
  20. }
  21. }

解码器:

  1. /*
  2. * Copyright (C) TD Tech<br>
  3. * All Rights Reserved.<br>
  4. *
  5. */
  6. package main.java.com.nionetty.client;
  7. import io.netty.buffer.ByteBuf;
  8. import io.netty.channel.ChannelHandlerContext;
  9. import io.netty.handler.codec.ByteToMessageDecoder;
  10. import java.nio.ByteBuffer;
  11. import java.util.List;
  12. /**
  13. * Create Date: 2014-11-4 下午02:42:21<br>
  14. * Create Author: lWX232692<br>
  15. * Description :
  16. */
  17. public class MyClientDecoder extends ByteToMessageDecoder {
  18. @Override
  19. protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
  20. List<Object> out) throws Exception {
  21. //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)
  22. if (buffer != null) {
  23. ByteBuffer msg = null;
  24. try {
  25. if(buffer.readableBytes() > 0 ){
  26. msg = ByteBuffer.allocate(buffer.readableBytes()) ;
  27. byte[] bb = new byte[buffer.readableBytes()] ;
  28. buffer.readBytes(bb) ;
  29. msg.put(bb);
  30. msg.flip();
  31. }
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. msg = null ;
  35. }
  36. if (msg != null) {
  37. out.add(msg);
  38. }
  39. }
  40. }
  41. }

业务handler:

  1. /*
  2. * Copyright (C) TD Tech<br>
  3. * All Rights Reserved.<br>
  4. *
  5. */
  6. package main.java.com.nionetty.client;
  7. import io.netty.buffer.ByteBuf;
  8. import io.netty.channel.ChannelHandlerContext;
  9. import io.netty.handler.codec.ByteToMessageDecoder;
  10. import java.nio.ByteBuffer;
  11. import java.util.List;
  12. /**
  13. * Create Date: 2014-11-4 下午02:42:21<br>
  14. * Create Author: lWX232692<br>
  15. * Description :
  16. */
  17. public class MyClientDecoder extends ByteToMessageDecoder {
  18. @Override
  19. protected void decode(ChannelHandlerContext ctx, ByteBuf buffer,
  20. List<Object> out) throws Exception {
  21. //UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 1, cap: 1024)
  22. if (buffer != null) {
  23. ByteBuffer msg = null;
  24. try {
  25. if(buffer.readableBytes() > 0 ){
  26. msg = ByteBuffer.allocate(buffer.readableBytes()) ;
  27. byte[] bb = new byte[buffer.readableBytes()] ;
  28. buffer.readBytes(bb) ;
  29. msg.put(bb);
  30. msg.flip();
  31. }
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. msg = null ;
  35. }
  36. if (msg != null) {
  37. out.add(msg);
  38. }
  39. }
  40. }
  41. }

测试通过,搞了因为在网上没有找到完整的实例,所以因为一个小问题,找了两天都没有找到原因,希望看到的同学能够有所收获

Netty实现SSL双向验证完整实例的更多相关文章

  1. 请给你的短信验证码接口加上SSL双向验证

    序言 去年年底闲来几天,有位同事专门在网上找一些注册型的app和网站,研究其短信接口是否安全,半天下来找到30来家,一些短信接口由于分析难度原因,没有继续深入,但差不多挖掘到20来个,可以肆意被调用, ...

  2. MQTT研究之EMQ:【SSL双向验证】

    EMQ是当前MQTT中,用于物联网领域中比较出色的一个broker,今天我这里要记录和分享的是关于SSL安全通信的配置和注意细节. 环境: 1. 单台Linux CentOS7.2系统,安装一个EMQ ...

  3. nginx配置ssl双向验证 nginx https ssl证书配置

    1.安装nginx 参考<nginx安装>:http://www.ttlsa.com/nginx/nginx-install-on-linux/ 如果你想在单IP/服务器上配置多个http ...

  4. Struts2的手工自定义验证--完整实例代码

    ActionSupport类实现了Validateable.ValidationAware接口, 其中Validateable接口就是验证器接口,该接口有一个validate()方法, validat ...

  5. MQTT研究之EMQ:【SSL证书链验证】

    1. 创建证书链(shell脚本) 客户端证书链关系: rootCA-->chainca1-->chainca2-->chainca3 ca caCert1 caCert2 caCe ...

  6. netty集成ssl完整参考指南(含完整源码)

    虽然我们在内部rpc通信中使用的是基于认证和报文头加密的方式实现安全性,但是有些时候仍然需要使用SSL加密,可能是因为对接的三方系统需要,也可能是由于open的考虑.中午特地测了下netty下集成ss ...

  7. 前后端API交互数据加密——AES与RSA混合加密完整实例

    前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...

  8. SSL 通信原理及Tomcat SSL 双向配置

    SSL 通信原理及Tomcat SSL 双向配置 目录1 参考资料 .................................................................. ...

  9. Https双向验证与Springboot整合测试-人来人往我只认你

    1 简介 不知不觉Https相关的文章已经写了6篇了,本文将是这个专题的最后一篇,起码近期是最后一篇.前面6篇讲的全都是单向的Https验证,本文将重点介绍一下双向验证.有兴趣的同学可以了解一下之前的 ...

随机推荐

  1. Codeforces E. Interesting Array(线段树)

    题目描述: D. Interesting Arraytime limit per test1 secondmemory limit per test256 megabytesinputstandard ...

  2. Python开发应用-正则表达进行排序搜索

    re模块提供了3个方法对输入的字符串进行确切的查询,match和search最多只会返回一个匹配条件的子串,可以理解为非贪婪模式,而findall会返回N个匹配条件的子串,可以理解为贪婪模式 re.m ...

  3. Linux下TCP连接断开后不释放的解决办法

    问题:在开发测试时发现断开与服务器端口后再次连接时拒绝连接. 分析:服务器上查看端口占用情况,假设端口为8888. netstat -anp |grep 8888 发现端口8888端口显示被占用(ip ...

  4. hdu6172&&hdu6185&&P5487——BM算法

    hdu6172 模板的简单应用 先根据题中的表达式求出前几项,再上BM,注意一下n的大小关系. #include <bits/stdc++.h> using namespace std; ...

  5. 五.python小数据池,代码块的最详细、深入剖析

    一,id,is,== 在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存中,那么这个空间是 ...

  6. 二、python介绍

    python第一篇-------python介绍 一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写Python语 ...

  7. 捷配制作PCB流程

    https://www.jiepei.com/orderprocess.html 以我的板子为例 查看下自己板子的信息 切换到mm 键盘 Q 压缩PCB文件 付款什么的自己哈 改天我有贴片的订单的时候 ...

  8. Linux下搭建iSCSI共享存储的方法 Linux-IO Target 方式CentOS7-1810下实现

    iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够在诸如高速 ...

  9. koa koa-static 静态资源中间件

    koa-static介绍 在网络请求中,请求往往分成两种类型,一种是静态资源,直接从服务器的文件存储中读取,一种是动态资源,一般需要先从数据库获取数据,然后经过一定的处理,最后返回给客户端. koa- ...

  10. K8S组件

    Master 组件 Master组件提供集群的管理控制中心.Master组件可以在集群中任何节点上运行.但是为了简单起见,通常在一台VM/机器上启动所有Master组件,并且不会在此VM/机器上运行用 ...