Akka原生支持SSL、HTTPS、HTTP 2,本文记录下各SSL的使用配置。
X.509证书
公钥证书是解决身份问题的一种方法。若仅加密是可以建立一个安全的连接,但不能保证你正在与你认为正在与之通信的服务器通信。如果没有某种方法来验证远程服务器的身份,攻击者仍然可以将自己作为远程服务器,然后将安全连接转发到伪造的远程服务器。公钥证书就是用来解决这个问题的。
考虑公共密钥证书的最佳方法是使用护照系统。证书用于以一种难以伪造的方式建立有关信息持有人的信息。这就是为什么证书验证如此重要:接受任何证书意味着即使是攻击者的证书也将被盲目接受。
生成 X.509 证书
本文示例使用Java 1.8的keytool
来创建证书。
生成随机密码
通过pwgen
命令生成10位字符的随机密码到password
文件,这个密码文件将在接下来各步骤中使用。
1
| pwgen -Bs 10 1 > password
|
Linux:sudo apt install pwgen
或sudo yum install pwgen
,Mac:brew install pwgen
服务器配置
你将需要一个分配了DNS主机名的服务器来验证主机名。在这个例子中,我们假设主机名是yangbajing.dev
。
创建自签名证书
生成服务端SSL证书
第一步是创建将对yangbajing.me
证书进行签名的证书颁发机构。根CA证书有几个附加属性(ca:true
,keyCertSign
),这些属性明确地将其标记为CA证书,并将保存在信任存储中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #!/bin/sh
export PW=`cat password`
KEY_FILE=ssl-key
keytool -genkeypair -v \ -dname "CN=www.yangbajing.me, OU=Yangbajing, O=Yangbajing, L=Beijing, ST=Beijing, C=CN" \ -keyalg RSA \ -keysize 4096 \ -ext KeyUsage:critical="keyCertSign" \ -ext BasicConstraints:critical="ca:true" \ -ext SAN="DNS:www.yangbajing.me,DNS:yangbajing.me,DNS:about.yangbajing.me" \ -validity 9999 \ -alias ${KEY_FILE} \ -keystore ${KEY_FILE}.jks \ -keypass:env PW \ -storepass:env PW
keytool -export -v \ -alias ${KEY_FILE} \ -file ${KEY_FILE}.crt \ -keypass:env PW \ -storepass:env PW \ -keystore ${KEY_FILE}.jks \ -rfc
|
生成 yangbajing.dev 证书
SSL证书配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #!/bin/sh
LANG=en_US.UTF-8 export PW=`cat password` export DOMAIN="yangbajing.dev" export KEY_FILE=ssl-key
keytool -genkeypair -v \ -alias ${DOMAIN} \ -dname "CN=${DOMAIN}, OU=Yangbajing, O=Yangbajing, L=Beijing, ST=Beijing, C=CN" \ -keystore ${DOMAIN}.jks \ -keypass:env PW \ -storepass:env PW \ -keyalg RSA \ -keysize 2048 \ -validity 385
keytool -certreq -v \ -alias ${DOMAIN} \ -keypass:env PW \ -storepass:env PW \ -keystore ${DOMAIN}.jks \ -file ${DOMAIN}.csr
keytool -gencert -v \ -alias ${KEY_FILE} \ -keypass:env PW \ -storepass:env PW \ -keystore ${KEY_FILE}.jks \ -infile ${DOMAIN}.csr \ -outfile ${DOMAIN}.crt \ -ext KeyUsage:critical="digitalSignature,keyEncipherment" \ -ext EKU="serverAuth" \ -ext SAN="DNS:${DOMAIN}" \ -rfc
keytool -import -v \ -alias ${KEY_FILE} \ -file ${KEY_FILE}.crt \ -keystore ${DOMAIN}.jks \ -storetype JKS \ -storepass:env PW << EOF yes EOF
keytool -import -v \ -alias ${DOMAIN} \ -file ${DOMAIN}.crt \ -keystore ${DOMAIN}.jks \ -storetype JKS \ -storepass:env PW
|
可以列出yangbajing.jks
的内容以确认。若使用Play
(等Java应用),这将存储到服务器的密钥存储区。
1
| keytool -list -v -keystore yangbajing.jks -storepass:env PW
|
将可看到类似如下输出:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Keystore type: jks Keystore provider: SUN
Your keystore contains 1 entry
Alias name: yangbajing.dev Creation date: Jun 18, 2019 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=yangbajing.dev, OU=Yangbajing, O=Yangbajing, L=Beijing, ST=Beijing, C=CN Issuer: CN=yangbajing.dev, OU=Yangbajing, O=Yangbajing, L=Beijing, ST=Beijing, C=CN ....
|
导出Nginx可用的PEM
如果 yangbajing.me 不使用Java作为TLS端点,同时你想使用Nginx。可需要导出 PEM 格式的证书。这需要 openssl
来导出私钥。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #!/bin/sh
export PW=`cat password` DOMAIN=hongkazhijia.dev
keytool -export -v \ -alias ${DOMAIN} \ -file ${DOMAIN}.crt \ -keypass:env PW \ -storepass:env PW \ -keystore ${DOMAIN}.jks \ -rfc
keytool -importkeystore -v \ -srcalias ${DOMAIN} \ -srckeystore ${DOMAIN}.jks \ -srcstoretype jks \ -srcstorepass:env PW \ -destkeystore ${DOMAIN}.p12 \ -destkeypass:env PW \ -deststorepass:env PW \ -deststoretype PKCS12
openssl pkcs12 \ -nocerts \ -nodes \ -in ${DOMAIN}.p12 \ -out ${DOMAIN}.key \ -passout env:PW \ -passin env:PW
rm ${DOMAIN}.p12
|
生成的 yangbajing.dev.crt
(公钥)和 yangbajing.dev.key
(私钥)两个文件。作为示例,可以这样配置Nginx使用。
1 2
| ssl_certificate /etc/nginx/certs/yangbajing.dev.crt; ssl_certificate_key /etc/nginx/certs/yangbajing.dev.key;
|
如果使用的是客户端身份验证,还需要添加:
1 2
| ssl_client_certificate /etc/nginx/certs/clientca.crt; ssl_verify_client on;
|
可以通过如下命令来检查服务器的证书(需要先启动 yangbajing.dev HTTP服务器):
1
| keytool -printcert -sslserver yangbajing.dev
|
HTTP 2
TODO
小结
TODO