在Netty中支持https服务器

一、生成测试证书 1、安装Openssl sudo apt-get install openssl 2、生成证书( openssl生成证书 - fengmenghello的日志 - 网易博客) # 设定相关的目录 mkdir -p /etc/ssl mkdir -p /etc/ssl/private chmod og-rwx /etc/ssl/private mkdir -p /etc/ssl/certs mkdir -p /etc/ssl/crl mkdir -p /etc/ssl/newcerts # 设定 OpenSSL 设定档[3] mv /usr/share/ssl/openssl.cnf /etc/ssl ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf # 设定 OpenSSL 设定档的位置[4] export OPENSSL_CONF="/etc/ssl/openssl.cnf" # 把 OpenSSL 设定档的位置加进 .bashrc 中[5] echo "# OpenSSL 设定档的位置" >> ~/.bashrc echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc # 制作乱数档[6] openssl rand -out /etc/ssl/private/.rand 1024 chmod og-rwx /etc/ssl/private/.rand 然后修改 /etc/ssl/openssl.cnf ,把这一行 dir = ./demoCA # Where everything is kept 改成这样 dir = /etc/ssl # Where everything is kept 制作最高层认证中心 (Root CA) 若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。 假设你要做的最高层认证中心叫做 myrootca 。 1. 制作 Private Key (及 Public Key ) 这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。 请为最高层认证中心的 Private Key 设定一个适当的密码。 # 制作 RSA[7] Private Key openssl genrsa -des3 -out /etc/ssl/private/myrootca.key 2048 chmod og-rwx /etc/ssl/private/myrootca.key 2. 填写凭证申请书 凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考「什么是凭证?」。 若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考「其她 SSL/X.509 凭证的做法」。 若不知如何填写,请参阅「如何填写凭证申请书」。 # 填写凭证申请书 openssl req -new -key /etc/ssl/private/myrootca.key -out /tmp/myrootca.req 3. 签发凭证 最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考「什么是最高层认证中心?」。 最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签 7305 天(大约 20年)。若不设效期的话,预设是 30 天(一个月)。 签完凭证,凭证申请书就不用了,可以删掉。 # 自己给自己签名 openssl x509 -req -days 7305 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_ca -signkey /etc/ssl/private/myrootca.key -in /tmp/myrootca.req -out /etc/ssl/certs/myrootca.crt # 删除凭证申请书 rm -f /tmp/myrootca.req 这样就好了。 Private Key 在 /etc/ssl/private/myrootca.key ,自己签名的 Public Key 凭证在 /etc/ssl/certs/myrootca.crt 。 myrootca.key 是 Private Key ,要小心存好保护,只有 root 才能读,权限建议 0444 。 myrootca.crt 是 Public Key 凭证,要尽量散出去,让大家用。最好放到内部网路上,或放到网站上,让大家自己下载,自己加进去。 制作伺服器用的凭证 假设你要做 myhost 的凭证: 1. 制作 Private Key (及 Public Key ) 这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。 请先登入到要用凭证的那台伺服器上。 注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。 # 制作 RSA Private Key openssl genrsa -out /etc/ssl/private/myhost.key 2048 chmod og-rwx /etc/ssl/private/myhost.key 2. 填写凭证申请书 凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考「什么是凭证?」。 若不知如何填写,请参阅「如何填写凭证申请书」。 # 填写凭证申请书 openssl req -new -key /etc/ssl/private/myhost.key -out /tmp/myhost.req 3. 用最高层认证中心签发凭证[8] 伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。 签完凭证,凭证申请书就不用了,可以删掉。 # 签发凭证 openssl x509 -req -days 3650 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_req -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key -CAserial /etc/ssl/myrootca.srl -CAcreateserial -in /tmp/myhost.req -out /etc/ssl/certs/myhost.crt # 删除凭证申请书 rm -f /tmp/myhost.req 这样就好了。[9] Private Key 在 /etc/ssl/private/myhost.key ,要小心存好保护,只有 root 才能读,建议权限为 0400 ; Public Key 凭证在 /etc/ssl/certs/myhost.crt ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhost 的 SSL 凭证,用在 HTTPS 或 POP3S/TLS/SSL 上。最好不要把档案搬到别的地方。你可以在设定档里,把凭证位置设定到这里。 Private Key 不要到处放,以免不小心忘记保护。
三、把证书导入KeyStore( Setting Up SSL with Netty ) 1、生成keystore keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore 2、导入证书 keytool -import -alias root -keystore tomcat.keystore -trustcacerts –file myhost.crt
四、代码中使用HTTPS ChannelPipeline pipeline = ch .pipeline();

try { SSLContext sslcontext = SSLContext.getInstance( "TLS" ); KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" ); KeyStore ks = KeyStore.getInstance( "JKS" ); String keyStorePath = "/data/vhosts/youli_server/certs/tomcat.keystore" ; String keyStorePassword = "XXXXXXXX" ; ks .load( new FileInputStream( keyStorePath ), keyStorePassword .toCharArray()); String keyPassword = "XXXXXXXX" ; kmf .init( ks , keyPassword .toCharArray()); sslcontext .init( kmf .getKeyManagers(), null , null ); SSLEngine sslEngine = sslcontext .createSSLEngine(); sslEngine .setUseClientMode( false ); sslEngine .setNeedClientAuth( false ); pipeline .addLast( new SslHandler( sslEngine )); //务必放在第一位 logger .info( "initChannel: addLast SslHandler" ); } catch (Exception e ) { e .printStackTrace(); }
pipeline .addLast( new ReadTimeoutHandler(60,TimeUnit. SECONDS )); pipeline .addLast( new WriteTimeoutHandler(60,TimeUnit. SECONDS )); pipeline .addLast( new HttpRequestDecoder()); pipeline .addLast( new HttpResponseEncoder()); pipeline .addLast( new HttpObjectAggregator(1048576)); pipeline .addLast( new ChunkedWriteHandler()); pipeline .addLast( new XChannelHandler());






    推荐阅读