最近在做SpringBoot OAuth2.0认证服务器,在本地测试时遇到一个SSL问题。印度尼西亚的Richard用AutoSSL配的证书是给服务器域名的,本地localhost测试环境不适用,需要我重新生成测试版的SSL。
两个工具Keytool和OpenSSL。
Keytool可以生成Self-signed Certificate(自签名证书),能用但浏览器会报证书错误,你忽略那个错误点Proceed,还是能访问。具体操作我下一篇说。
OpenSSL可以生成CA-signed Certificate(
两种方式都很简单,我把OpenSSL的步骤贴在下面。
操作环境:Mac
上重点!
第一部分,成为CA (Certified Authority)
1-1 / 生成root certificate的privat key
openssl genrsa -des3 -out ca.key 2048
有个密码保护,防止别人获得这个private key,生成他们的CA,再生成相关的SSL证书。
1-2/ 生成root certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
中间会问一下信息,如机构名等(挺无聊的)。关键是CN (Common Name),要填localhost!
1-3/ Mac电脑用户需要把这个root certificate (ca.crt)导入到Keychain
打开Keychain -> 选择File 菜单 -> Import Items -> 选择ca.crt -> 在Keychain搜索localhost,这是我们设置的common name,找到证书 -> 点开,选择Always trust
你会发现证书的❌变成了☑️
你这时,会有ca.key和ca.crt这两个文件,你就成为了CA。
第二部分,我们开始生成SSL证书
2-1/ 生成SSL证书的private key
openssl genrsa -out server.key 2048
2-2/ 生成SSL证书 请求(Certificate Request)
openssl req -new -key server.key -out server.csr
2-3/ 创建一个配置文件server.ext,内容如下
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName=@alt_names
[alt_names]
DNS.1=localhost
关键是DNS.1=localhost, 不然浏览器会报证书错误,NET::ERR_CERT_COMMON_NAME_INVALID
2-4/ 生成SSL证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile server.ext
第三部分,我们把SSL证书和相关的private key导到Java支持的Keystore中
3-1/ 把SSL证书的private key和SSL证书合并为一个PKCS12格式的文件
openssl pkcs12 -export -in server.crt -inkey server.key > server.p12
3-2/ 导入
keytool -importkeystore -srckeystore server.p12 -destkeystore server.jks -srcstoretype pkcs12
这时,我们会有server.jks文件,就是Java SSL配置需要的了
第四部分,配置Java
打开你的SpringBoot应用程序,找到applicaiton.properties
server.port = 8082 # HTTPS的端口
server.ssl.enabled=true #使用SSL
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:server.jks # 同trust.store
server.ssl.key-store-password=localhost # 同trust.store.password
#server.ssl.key-alias=spring_boot_ssl # keystore只有一个key,也就没有什么alias来找相关证书了,这个不需要。
trust.store=classpath:server.jks
trust.store.password=localhost # 这是你自己在生成证书中生成的密码,我建议从头到尾用一个,省的不清楚是root certificate还是SSL certificate的。
就好啦!
我端口设置在8082
如果你打开https://localhost:8082/hello,就会发现URL地址前有个小钥匙,浏览器也没有报任何错误,配置成功!
如果你打开http://localhost:8082/hello,浏览器会说需要TLS。
如果你想HTTP自动跳转HTTPS,可以再添加这个Java文件 (AppConfig.java)。这时你打开http://localhost:8081/hello,它会自动跳转到https://localhost:8082/hello
完整代码在 https://github.com/tutehub/sample-spring/tree/develop/ssl。