0%

springboot证书单向/双向认证

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 双向认证测试

  1. 创建服务端信任库
  2. 创建客户端证书
  3. 将客户端证书添加到服务端信任库
  4. postman 设置选择:setting - General - 关闭SSL certificate verification
  5. postman 设置选择:setting - Certificates - Client Certificates - 选择 Add Certificates
  6. 设置地址端口号CAR fileKEY file,证书有密码就输入Passphrase
  7. 测试