這次使用的Netty是最新的5.0 Alpha2版本,下載地址是:http://dl.bintray.com/netty/downloads/netty-5.0.0.Alpha2.tar.bz2,發布時間是2015年3月,到現在快一年了,咋還不更新呢?有些奇怪……
制作一張自簽證書(jks格式)
#keytool -genkey -keysize 2048 -validity 365 -keyalg RSA -dnam e "CN=gornix.com" -keypass 654321 -storepass 123456 -keystore gornix.jks
keytool為JDK提供的生成證書工具
- -keysize 2048 密鑰長度2048位(這個長度的密鑰目前可認為無法被暴力破解)
- -validity 365 證書有效期365天
- -keyalg RSA 使用RSA非對稱加密算法
- -dname "CN=gornix.com" 設置Common Name為gornix.com,這是我的域名
- -keypass 654321 密鑰的訪問密碼為654321
- -storepass 123456 密鑰庫的訪問密碼為123456(其實這兩個密碼也可以設置一樣,通常都設置一樣,方便記)
- -keystore gornix.jks 指定生成的密鑰庫文件為gornix.jks
完了之后就拿到了gornix.jks這個密鑰庫文件了,把它放到自己的home目錄下,比如:/home/guogangj/gornix.jks
在程序初始化的時候生成SSLContext
keyStore ks = KeyStore.getInstance("JKS"); InputStream ksInputStream = new FileInputStream("/home/guogangj/gornix.jks"); ks.load(ksInputStream, "123456".toCharArray()); keyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, "654321".toCharArray()); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), null, null);
這個過程在整個程序周期只需要做一次,最好try-catch一下,以便檢查異常,好了之后保存好sslContext,后面用到。
在ChannelInitializer的initChannel中
@Override protected void initChannel(SocketChannel socketChannel) throws Exception { SSLEngine sslEngine = sslContext.createSSLEngine(); sslEngine.setUseClientMode(false); //服務器端模式 sslEngine.setNeedClientAuth(false); //不需要驗證客戶端 socketChannel.pipeline().addLast("ssl", new SslHandler(sslEngine)); //搞定 //... }
sslContext就是前面生成的那個sslContext,通常可以用參數的形式傳入到ChannelInitializer中。還有,記得把SslHandler放在其它Handler的前面。
完成
搞定了,easy?可見SSL也沒什么神秘的,就是在普通的TCP連接基礎上包了一層處理而已(但如果要自己實現這層處理那可是相當復雜的),這層處理體現在Netty中就是一個SslHandler,把這個SslHandler加入到TCP連接的處理管線中即可。這篇文章並不是一篇完整的教程,本來我打算把它寫得完整一點,但這得花費較長的時間和篇幅,Netty雖然大大簡化了Java的網絡程序的開發,但要從頭到尾講清楚,也蠻有難度的,學習Netty目前主要有這兩本書:國內作者寫的《Netty權威指南》和國外作者寫的《Netty in Action》,英文好的當然推薦看后者,但兩本書都不是針對最新的Netty 5.0所寫,所以想深入的話還得看看Netty的源代碼和官方文檔(個人覺得也不太完善)。以后看看有沒有時間,有的話再寫些完整的教程出來。