Lettuce连接Redis集群遇PKIX证书错误,如何配置信任库?
解决Lettuce连接加密Redis集群的PKIX路径异常问题
方案1:代码中直接加载PEM证书(推荐,无需修改系统信任库)
这种方式不需要修改系统或全局信任库,直接在代码中加载Redis Labs提供的redis_ca.pem证书,适合单个项目快速解决问题。
- 将
redis_ca.pem放到项目资源目录(如src/main/resources) - 编写代码加载证书并构建SSLContext:
import io.lettuce.core.RedisURI; import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.io.InputStream; import java.security.KeyStore; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public class RedisClusterSslDemo { public static void main(String[] args) throws Exception { // 加载PEM格式的CA证书 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); try (InputStream certInputStream = RedisClusterSslDemo.class.getResourceAsStream("/redis_ca.pem")) { X509Certificate caCert = (X509Certificate) certFactory.generateCertificate(certInputStream); // 创建临时KeyStore并添加证书 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("redis-ca-cert", caCert); // 初始化信任管理器工厂 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); // 构建SSL上下文 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); // 配置Redis集群连接信息,开启SSL并传入自定义SSLContext RedisURI redisUri = RedisURI.Builder.redis("your-cluster-host", 6379) .withSsl(true) .withSslContext(sslContext) .withPassword("your-redis-password".toCharArray()) .build(); // 创建集群客户端并测试连接 RedisClusterClient clusterClient = RedisClusterClient.create(redisUri); try (StatefulRedisClusterConnection<String, String> connection = clusterClient.connect()) { connection.sync().set("test-key", "ssl-test-value"); System.out.println("连接成功,测试值:" + connection.sync().get("test-key")); } finally { clusterClient.shutdown(); } } } }
方案2:正确导入证书到自定义信任库(适合多项目共享)
如果需要多个项目共用该证书,可以将证书导入自定义信任库,避免修改系统默认的cacerts(容易出现权限、JDK版本不匹配问题)。
步骤1:生成自定义信任库
使用keytool命令生成专属信任库,替换命令中的路径和密码:
keytool -importcert -file /path/to/redis_ca.pem -alias redis-ca -keystore redis-truststore.jks -storepass your-truststore-pass
-file:指定redis_ca.pem的绝对路径-alias:给证书设置唯一别名(方便后续管理)-keystore:生成的信任库文件名(如redis-truststore.jks)-storepass:设置信任库密码(务必记住,后续配置需要)
步骤2:配置信任库
方式A:通过JVM启动参数指定
启动应用时添加以下参数,替换路径和密码:
java -Djavax.net.ssl.trustStore=/path/to/redis-truststore.jks -Djavax.net.ssl.trustStorePassword=your-truststore-pass -jar your-application.jar
此时代码中只需开启SSL即可:
RedisURI redisUri = RedisURI.Builder.redis("your-cluster-host", 6379) .withSsl(true) .withPassword("your-redis-password".toCharArray()) .build(); RedisClusterClient clusterClient = RedisClusterClient.create(redisUri);
方式B:代码中指定信任库
在代码启动时设置系统属性:
// 设置自定义信任库路径和密码 System.setProperty("javax.net.ssl.trustStore", "/path/to/redis-truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "your-truststore-pass"); // 后续连接代码同方式A
为什么之前导入cacerts没解决问题?
常见原因包括:
- 导入证书时使用的
cacerts路径与应用实际使用的JDK路径不匹配(不同JDK版本的cacerts位置不同) - 导入时输入的默认密码错误(系统默认
cacerts密码通常是changeit,注意拼写) - 导入证书后未重启应用,或者应用未读取到更新后的
cacerts
内容的提问来源于stack exchange,提问作者user51
相关产品推荐
相关产品推荐

