TLS/https
安全通信在现代应用程序中起着重要作用。客户端和服务器之间通过纯 HTTP 进行的通信不安全。对于用于生产的应用程序,应在应用程序中通过TLS(传输层安全性)协议启用HTTPS。
HTTPS 即 HTTP over TLS。TLS为客户端与服务器之间的数据传输提供安全保护。安全套接层(SSL)和传输层安全性协议(TLS)通常可以互换使用,但它们并不相同,SSL是TLS的前身。 TLS 分为单向或双向认证。
在单向TLS中, 只有客户端验证服务器以确保客户端从受信任的服务器上接收数据。客户端共享服务器的公共证书。
双向 TLS (Mutual TLS,mTLS)中, 客户端和服务器端都需要验证对方的身份,以保证参与的双方都是可信的。mTLS中双方共享自己的公共证书。
在大多数情况下,当我们的应用程序需要通过 SSL/TLS 进行通信时,我们会使用 keystore 和 truststore。
- Keystore 可以存放除了证书、公钥外其它敏感信息,比如密码、私钥……证书可以是关联的证书或者一个证书链。证书链有客户端证书和一个或多个CA证书。
- Truststore 仅仅包含客户端信任的证书、公钥。它无法存放敏感信息。
通常,这些是受密码保护的文件,与我们正在运行的应用程序位于同一文件系统上。在 Java 8 之前,用于这些文件的默认格式是 JKS。
从 Java 9 开始,默认的 keystore 格式是 PKCS12。JKS 和 PKCS12 最大的区别在于 JKS 是 Java 特有的格式,而 PKCS12 是存储加密私钥和证书的标准化和语言中立的方式。
以Java程序为例,我们建立SSLContext时,需要生成KeyManager和TrustManager,对应的参数为javax.net.ssl.keyStore和javax.net.ssl.trustStore。而它们的作用正好体现了不同Store的作用:
- TrustManager:决定对方来的cert是不是可信的;
- KeyManager:决定自己发什么cert给对方。
如果不指定 TrustStore,默认是 $JAVA_HOME/jre/lib/security/cacerts
文件。可以通过命令查看这个文件都有什么 certs:
|
|
生成密钥对
要启用 TLS,我们需要创建一个公共/私有密钥对。使用 JDK 自带密钥工具 keytool。
|
|
JKS 密钥库使用专用格式。建议使用 “keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12” 迁移到行业标准格式 PKCS12。
- alias:密钥别名,放入 keystore 中不冲突就行;
- keyalg:秘钥算法名称 RSA
- keysize:密钥位大小,2048基本就不可能破解了
- sigalg: 签名算法名称
- keypass 密钥口令
- keystore:密钥库名称
- storepass 密钥库口令
- storetype 密钥库类型 PKCS12
- dname:这个很关键,特别是CN=后面要按正确的域名来写
- validity:有效期天数
|
|
私钥是不能通过文件导出的,私钥文件只能通过代码来导出
|
|
Java 指定 keystore 和 truststore
|
|
如果没有显示指定上述属性,那么 JVM 默认使用 $JAVA_HOME/lib/security/cacerts
文件作为 truststore,并读取其中的授信证书(默认密码为changeit)。
在 Spring 中配置单向 TLS
|
|
因为这是自签名的cert,并不被Chrome所认可,所以会校验失败。以前的Chrome版本只是警告,但还是可以访问的,现在新版本的已经不能访问了。
|
|
双向 mTLS
|
|
Java 安全套接字扩展 (JSSE) 参考指南
JSSE Standard API The JSSE standard API, available in the javax.net and javax.net.ssl packages, provides:
- Secure sockets tailored to client and server-side applications.
- A non-blocking engine for producing and consuming streams of TLS/DTLS data (SSLEngine).
- Factories for creating sockets, server sockets, SSL sockets, and SSL server sockets. By using socket factories, you can encapsulate socket creation and configuration behavior.
- A class representing a secure socket context that acts as a factory for secure socket factories and engines.
- Key and trust manager interfaces (including X.509-specific key and trust managers), and factories that can be used for creating them.
- A class for secure HTTP URL connections (HTTPS).
OpenFeign 配置 https
在具体的 @FeignClient 上配置 configuration,此配置优先级次之,相同配置会被上一个覆盖。此类不能有 @Configuration 注解,否则会被全局扫描到,变成了全局配置,此外方法上必须标注 @Bean 才能生效。
|
|
附录
- Public-Key Cryptography Standards (PKCS)
- Java Secure Socket Extension (JSSE) Reference Guide
- https://keystore-explorer.org/index.html
- https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl
- https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#tls-and-ssl