netty实现tls双向证书认证

Netty结合TLS实现双向认证

netty代码如下

public static EventLoopGroup groupStream = new NioEventLoopGroup();


public void initClient() {
        try {
            Bootstrap b = new Bootstrap();
            b.group(groupStream)
                    .channel(NioSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel sc) throws SSLException {
                          
                            if (v.isStreamsInTlsOn()) {//是否开启tls认证
                                SSLEngine engine = null;
                                if (Node.isOpenKnockerHandler){
                                //双向认证   tlsTowAuthorKeyPath:证书路径,双向证书,客户端证书路径 、 tlsTowAuthorCaPath:证书路径,双向证书,根证书路径
                                    engine = SslContextFactory.getClientContext(Node.tlsTowAuthorKeyPath,Node.tlsTowAuthorCaPath).createSSLEngine();
                                }else {
                                //单向认证
                                    String cChatPath =  System.getProperty("user.dir") + "/Data/keys/client.jks";
                                    engine = SslContextFactory.getClientContext(cChatPath,cChatPath).createSSLEngine();
                                }
                                engine.setUseClientMode(true);
                                sc.pipeline().addLast("ssl", new SslHandler(engine));
                            }
                            sc.pipeline().addLast(new IdleStateHandler(45, 0, 0));    //45s无接收时,发送心跳
                            ByteBuf buf = Unpooled.copiedBuffer(KConst.SEPERATOR.getBytes());
                            sc.pipeline().addLast(new DelimiterBasedFrameDecoder(KConst.MAX_FRAME_LENGTH, buf));
                            sc.pipeline().addLast(new StringDecoder(UTF_8));
                            sc.pipeline().addLast(new HandlerStream(Client.this, handleMsg, heartMsg));
                        }
                    });
        
        } catch (Exception e) {
            log.error("[Thread_Stream] exception!", e);
            throw new RuntimeException(e);
        }
    }


import com.Node.Node.Node;
import lombok.extern.slf4j.Slf4j;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;

/**
 * @description: ssl工厂类
 * @date: 2022/1/18 16:15
 */
@Slf4j
public class SslContextFactory {

private static SSLContext CLIENT_CONTEXT;

private static final String PROTOCOL = "TLS";

/**
     * @description: 获取客户端SSLContext
     * @date: 2022/1/18 16:16
     */
    public static SSLContext getClientContext(String pkPath,String caPath){
        String pkPassword = "";
        String caPassword = "";
        if (Node.isOpenKnockerHandler){
            pkPassword = "123456";//授权登录密码
            caPassword = Node.caJksPwd;//证书密码
        }else {
            pkPassword = "ponshine";
            caPassword = "ponshine";
        }

        if(CLIENT_CONTEXT!=null) {
            return CLIENT_CONTEXT;
        }
        InputStream in = null;
        InputStream tIN = null;
        try{
            KeyManagerFactory kmf = null;
            if (pkPath != null) {
                KeyStore ks = KeyStore.getInstance("JKS");
                in = new FileInputStream(pkPath);
                ks.load(in, pkPassword.toCharArray());
                kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(ks, pkPassword.toCharArray());
            }
            TrustManagerFactory tf = null;
            if (caPath != null) {
                KeyStore tks = KeyStore.getInstance("JKS");
                tIN = new FileInputStream(caPath);
                tks.load(tIN, caPassword.toCharArray());
                tf = TrustManagerFactory.getInstance("SunX509");
                tf.init(tks);
            }
            CLIENT_CONTEXT = SSLContext.getInstance(PROTOCOL);
            //初始化此上下文
            //参数一:认证的密钥      参数二:对等信任认证  参数三:伪随机数生成器 。 由于单向认证,服务端不用验证客户端,所以第二个参数为null
            CLIENT_CONTEXT.init(kmf.getKeyManagers(),tf.getTrustManagers(), null);
        }catch(Exception e){
            log.warn("[SslContextFactory-getClientContext] exception",e);
            throw new Error("Failed to initialize the client-side SSLContext");
        }finally{
            if(in !=null){
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("",e);
                }
            }
            if (tIN != null){
                try {
                    tIN.close();
                } catch (IOException e) {
                    log.error("",e);
                }
            }
        }
        return CLIENT_CONTEXT;
    }


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值