欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

netty集成ssl双向验证

程序员文章站 2022-03-02 15:24:54
...

netty集成ssl双向验证

文章分为两部分,

  1. 生成服务器和客户端两个证书
  2. 将证应用到netty中

生成证书用到jak自带的工具,一会再讲,先看如果假设我们已经有两个证书(服务器和客户端)如何写程序

	
	服务器上要添加sslhandler,参数是sslEngine,而engine由sslContext创建
	p.addLast(new SslHandler(context.newEngine(socketChannel.alloc())));


  1. 服务器,创建sslContext
	
	public static SslContext getSslContextService() {
		List<String> ciphers = Arrays.asList("ECDHE-RSA-AES128-SHA", "ECDHE-RSA-AES256-SHA", "AES128-SHA", "AES256-SHA", "DES-CBC3-SHA");
		try {
		//创建KeyStore
			KeyStore keyStore = KeyStore.getInstance("JKS");
		//加载证书,第一个参数是一个指向服务器证书的流,第二个参数是证书密码转成char数组	
			keyStore.load(ResourceManager.gerResourceForFile("sChat.jks"), "密码".toCharArray());
		
		//创建KeyManagerFactory(**管理器,不带这个过不去客户端的信任管理器)
			KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
			keyManagerFactory.init(keyStore, "密码".toCharArray());

		//信任管理器(信任列表的客户端才会被接受)
			TrustManagerFactory tf = TrustManagerFactory.getInstance("SunX509");
			tf.init(keyStore);

		//SslContextBuilder创建sslcontext
		return SslContextBuilder
					.forServer(keyManagerFactory)
					.trustManager(tf)
					.ciphers(ciphers)
					.clientAuth(ClientAuth.REQUIRE) //必须校验客户端
					//要用openssl,必须在maven中添加 netty-tcnative-boringssl-static 才行
					.sslProvider(SslProvider.OPENSSL)
					.build();
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new IllegalArgumentException("无法创建SslContext");
	}
	

  1. 客户端相同道理,也要创建 sslContext
	
	public static SslContext getSslContextClient() {
	List<String> ciphers = Arrays.asList("ECDHE-RSA-AES128-SHA", "ECDHE-RSA-AES256-SHA", "AES128-SHA", "AES256-SHA", "DES-CBC3-SHA");
		try {
			//同理
			KeyStore keyStore = KeyStore.getInstance("JKS");
			//客户端证书的流 和 客户端证书密码
			keyStore.load(ResourceManager.gerResourceForFile("cChat.jks"), "密码".toCharArray());
			//
			TrustManagerFactory tf = TrustManagerFactory.getInstance("SunX509");
			//初始化
			tf.init(keyStore);

			KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
			keyManagerFactory.init(keyStore, "密码".toCharArray());

			return SslContextBuilder
					.forClient()
					.trustManager(tf)
					.keyManager(keyManagerFactory)
					.ciphers(ciphers)
					.sslProvider(SslProvider.OPENSSL) //同样也要加入相应jar包
					.build();
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new IllegalArgumentException("无法创建SslContext");
	}


上面两步是根据证书创建sslContext的方法,接下来将如何生成证书

第一步: 生成Netty服务端私钥和证书(高版本的java可能会提示升级转换之类的,复制他的提示,直接运行会产生因版本的证书)

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

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

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

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

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

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

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

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

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

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

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

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

以上生成的两个后缀为jks的文件,两个后缀为cer的文件,我们将cChat.jks作为客户端生成sslcontext的文件,sChat.jks作为服务器生成sslContext的文件,即可。
相关标签: netty