一、生成测试证书
1、安装Openssl
sudo apt-get install openssl
# 设定相关的目录
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());