springboot单向认证和双向认证
- 单向认证
服务端开启 SSL 证书,通过 springboot 或者 nginx 都可以实现, 开启单向认证后访问服务端接口需要使用 https 协议即可。
server:
port: 8443
ssl:
enabled: true
#服务端证书路径, classpath:local-dev.p12
key-store: classpath:server.jks
#证书密码
key-store-passwd: 123456
#证书类型
key-store-type: JKS
- 双向认证
springboot 服务端除了开启 SSL 证书,还要开启客户端证书认证client-auth: need
, 需要将客户端证书导入到服务端信任库
中, 否则访问报错, 提示无法建立连接, 不接受您的登录证书, 或者您可能没有提供登录证书
等报错信息.
server:
port: 8443
ssl:
enabled: true
#服务端证书路径, classpath:local-dev.p12
key-store: classpath:server.jks
#证书密码
key-store-passwd: 123456
#证书类型
key-store-type: JKS
#是否需要进行认证,可选: need/want/none
client-auth: need
#可信任的客户端证书, classpath:local-dev.p12
trust-store: classpath:server.jks
#密码,即步骤一中输入的密码
trust-store-password: 123456
trust-store-type: JKS
使用 keytool 创建证书
# 创建 test_server, 如果是单向认证创建完 test_server.jks 并配置正确即可.
keytool -genkeypair -alias test_server -keypass 123456 -storepass 123456 -dname "C=CN,ST=JS,L=NJ,O=test,OU=dev,CN=test.server.cn" -keyalg RSA -keysize 20
48 -validity 3650 -keystore test_server.jks
# 双向认证还需要进行以下步骤
# 使用 keytool 创建 test_client 证书库
keytool -genkeypair -alias test_client -keypass 123456 -storepass 123456 -dname "C=CN,ST=JS,L=NJ,O=test,OU=dev,CN=test.client.cn" -keyalg RSA -keysize 20
48 -validity 3650 -keystore test_client.jks
# 从证书库中导出客户端证书, 注意:加上 -rfc 选项输出PEM编码格式的证书, 否则导入服务端信任库会报错.
keytool -exportcert -keystore test_client.jks -rfc -file test_client.cer -alias test_client -storepass 123456
# 将客户端证书导入到服务端信任库
keytool -importcert -keystore test_server.jks -file test_client.cer -alias test_client -storepass 123456 -noprompt
在信任库中, 导入后的证书为
trustedCertEntry
实体类型,而私钥证书为PrivateKeyEntry
.
上述操作完成后, 就可以通过客户端证书调用服务端接口,但是想要服务端调用客户端,需要按照上述步骤将服务端证书导入到客户端信任库.
- keytool 查看
证书库
详情
keytool -list -keystore test_server.jks -storepass 123456
# 加 -v 查看详情
keytool -list -v -keystore test_server.jks -storepass 123456
- keytool 查看
证书
详情
keytool -printcert -file test_client.cer
openssl 创建自签名证书
# 创建私钥(.key)
openssl genrsa -out my.key 2048
# 基于私钥(.key)创建证书签名请求(.csr)
openssl req -new -key my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
# (可选)直接同时生成私钥(.key)和证书签名请求(.csr)
openssl req -new -newkey rsa:2048 -nodes -keyout my.key -out my.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
# 使用自己的私钥(.key)签署自己的证书签名请求(.csr),生成自签名证书(.crt)
openssl x509 -req -in my.csr -out my.crt -signkey my.key -days 3650
# (可选)直接同时生成私钥(.key)和自签名证书(.crt)
openssl req -x509 -newkey rsa:2048 -nodes -keyout my.key -out my.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
openssl 创建私有CA签发的证书
# 生成CA私钥(ca.key)和CA自签名证书(ca.crt)
openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
# 生成Server端私钥(server.key)和证书签名请求(server.csr)
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=domain1/CN=domain2"
# 使用CA证书(ca.crt)与密钥(ca.key)签署服务器的证书签名请求(server.csr),生成私有CA签名的服务器证书(server.crt)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
# 验证server.crt是否真得是由ca签发的, 结果显示 ok
openssl verify -CAfile ca.crt server.crt
openssl创建的证书导入java证书信任库
keytool -importcert -keystore test_server.jks -file openssl_client.crt -alias test_client -storepass 123456 -noprompt
证书格式转换(参考链接)
- jks / pkcs12 格式转换
# jks 转 p12
keytool -importkeystore -srckeystore server.keystore -destkeystore server.p12 -srcalias serverkey -destalias serverkey \
-srcstoretype jks -deststoretype pkcs12 -srcstorepass 111111 -deststorepass 111111 -destkeypass 111111 -noprompt
# p12 转 jks 同理
keytool -importkeystore -srckeystore server.p12 -destkeystore server.keystore \
-srcstoretype pkcs12 -deststoretype jks -srcalias server -destalias server \
-deststorepass 111111 -srcstorepass 111111
- Nginx 证书 转 JKS
Java 通常使用 JKS 作为证书存储格式,而Nginx往往采用 PEM 证书格式
# pem证书和私钥合成p12,注意定义-name 选项,这将作为keystore识别实体的参数
openssl pkcs12 -export -in server.crt -inkey server.key -passin pass:111111 -password pass:111111 -name server -out server.p12
# p12 证书转jks 证书
keytool -importkeystore -srckeystore server.p12 -destkeystore server.keystore \
-srcstoretype pkcs12 -deststoretype jks -srcalias server -destalias server \
-deststorepass 111111 -srcstorepass 111111
如果 p12 文件中未指定实体名称,使用 keytool 转换时则不需提供 srcalias/destalias 参数,而输出的 keystore 实体名称默认为 1
- JKS 证书 转 Nginx证书
# jks 证书转p12
keytool -importkeystore -srckeystore server.keystore -destkeystore server.p12 \
-srcstoretype jks -deststoretype pkcs12 -srcalias server -destalias server \
-deststorepass 111111 -destkeypass 111111 -srcstorepass 111111
# p12 证书提取pem证书和私钥
openssl pkcs12 -in server.p12 -clcerts -nokeys -password pass:111111 -out server.crt
openssl pkcs12 -in server.p12 -nocerts -password pass:111111 -passout pass:111111 -out server.key
postman 双向认证测试
- 创建服务端信任库
- 创建客户端证书
- 将客户端证书添加到服务端信任库
postman
设置选择:setting
-General
- 关闭SSL certificate verification
postman
设置选择:setting
-Certificates
-Client Certificates
- 选择Add Certificates
- 设置
地址
和端口号
、CAR file
、KEY file
,证书有密码就输入Passphrase
- 测试