Springboot实现TLS双向认证

keytool 是 Java 自带的工具,适合与 JKS 密钥库和信任库一起使用。


一、生成自签名CA证书

  1. 生成CA密钥对和自签名证书

    bash 复制代码
    keytool -genkeypair -alias my-ca -keyalg RSA -keysize 2048 -validity 3650 -keystore ca.jks -storepass changeit -keypass changeit -dname "CN=My CA, OU=My Organization, O=My Company, L=My City, ST=My State, C=US" -ext bc:c
    • -alias my-ca:CA 证书的别名。
    • -keystore ca.jks:生成的密钥库文件(包含CA密钥对和证书)。
    • -storepass-keypass:密钥库和密钥的密码。
    • -dname:证书的 Distinguished Name(DN)。
    • -ext bc:c:将证书标记为 CA 证书。
  2. 导出CA证书

    bash 复制代码
    keytool -exportcert -alias my-ca -keystore ca.jks -storepass changeit -file ca.crt
    • -file ca.crt:导出的 CA 证书文件。

二、使用CA签发服务器证书

  1. 生成服务器密钥对

    bash 复制代码
    keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -validity 365 -keystore server.jks -storepass changeit -keypass changeit -dname "CN=server.example.com, OU=My Organization, O=My Company, L=My City, ST=My State, C=US"
    • -alias server:服务器证书的别名。
    • -keystore server.jks:生成的服务器密钥库文件。
  2. 生成证书签名请求(CSR)

    bash 复制代码
    keytool -certreq -alias server -keystore server.jks -storepass changeit -file server.csr
    • -file server.csr:生成的 CSR 文件。
  3. 使用CA签发服务器证书

    bash 复制代码
    keytool -gencert -alias my-ca -infile server.csr -outfile server.crt -keystore ca.jks -storepass changeit -validity 365 -ext SAN=dns:server.example.com
    • -infile server.csr:输入的 CSR 文件。
    • -outfile server.crt:签发的服务器证书文件。
    • -ext SAN=dns:server.example.com:可选,添加 Subject Alternative Name(SAN)。
  4. 将CA证书和服务器证书导入服务器密钥库

    bash 复制代码
    keytool -importcert -alias my-ca -file ca.crt -keystore server.jks -storepass changeit -noprompt
    keytool -importcert -alias server -file server.crt -keystore server.jks -storepass changeit
    • 先导入 CA 证书,再导入签发的服务器证书。

三、使用CA签发客户端证书

  1. 生成客户端密钥对

    bash 复制代码
    keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -validity 365 -keystore client.jks -storepass changeit -keypass changeit -dname "CN=client.example.com, OU=My Organization, O=My Company, L=My City, ST=My State, C=US"
    • -alias client:客户端证书的别名。
    • -keystore client.jks:生成的客户端密钥库文件。
  2. 生成证书签名请求(CSR)

    bash 复制代码
    keytool -certreq -alias client -keystore client.jks -storepass changeit -file client.csr
    • -file client.csr:生成的 CSR 文件。
  3. 使用CA签发客户端证书

    bash 复制代码
    keytool -gencert -alias my-ca -infile client.csr -outfile client.crt -keystore ca.jks -storepass changeit -validity 365
    • -infile client.csr:输入的 CSR 文件。
    • -outfile client.crt:签发的客户端证书文件。
  4. 将CA证书和客户端证书导入客户端密钥库

    bash 复制代码
    keytool -importcert -alias my-ca -file ca.crt -keystore client.jks -storepass changeit -noprompt
    keytool -importcert -alias client -file client.crt -keystore client.jks -storepass changeit
    • 先导入 CA 证书,再导入签发的客户端证书。

四、配置信任库

  1. 创建信任库并导入CA证书

    bash 复制代码
    keytool -importcert -alias my-ca -file ca.crt -keystore truststore.jks -storepass changeit -noprompt
    • -keystore truststore.jks:生成的信任库文件。

五、配置服务器和客户端

1. 服务器配置

在 Spring Boot 中配置:

yaml 复制代码
server:
  ssl:
    key-store: classpath:server.jks
    key-store-password: changeit
    key-alias: server
    trust-store: classpath:truststore.jks
    trust-store-password: changeit
    client-auth: need # 要求客户端提供证书
2. 客户端配置

在 Java 中配置:

java 复制代码
SSLContext sslContext = SSLContextBuilder.create()
        .loadKeyMaterial(Paths.get("client.jks"), "changeit".toCharArray(), "changeit".toCharArray())
        .loadTrustMaterial(Paths.get("truststore.jks"), "changeit".toCharArray())
        .build();
HttpClient client = HttpClients.custom()
        .setSSLContext(sslContext)
        .build();

六、总结

  • 使用 keytool 可以完全替代 openssl,生成和管理自签名 CA 证书、服务器证书和客户端证书。
  • 只需要将 CA 证书添加到信任库(truststore.jks),即可验证所有由该 CA 签发的证书。
  • 这种方法适合 Java 生态系统,尤其是使用 JKS 密钥库和信任库的场景。
相关推荐
RyFit9 小时前
SpringAI 常见问题及解决方案大全
java·ai
石山代码9 小时前
C++ 内存分区 堆区
java·开发语言·c++
绝知此事9 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
无风听海10 小时前
C# 隐式转换深度解析
java·开发语言·c#
一只大袋鼠10 小时前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git
德思特11 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
YOU OU11 小时前
Spring IoC&DI
java·数据库·spring
один but you12 小时前
从可变参数到 emplace:现代 C++ 性能优化的核心组合
java·开发语言
IT_陈寒12 小时前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
是码龙不是码农12 小时前
ThreadPoolExecutor 7 个核心参数详解
java·线程池·threadpool