Java JDBC Public 密钥连接失败:"unable to find valid certification path to requested target"
Java JDBC Public Key connection failed with: "unable to find valid certification path to requested target"
我想允许来自 java 客户端的连接。
此 Java 客户端需要为不同的数据库支持多个 public 密钥。
我必须使用 PUBLIC KEY
并且不能信任服务器证书。
我在网上搜索过,但找不到这个问题的完整解决方案,这些是我阅读过的一些链接:
first
third
我也读过这个 link 我的问题不是重复的,因为它是一个完全不同的连接类型 - 这是一个与连接管理器的 JDBC 连接,而不是一般的 URL 连接使用 SSL。
还有很多,我发现的所有堆栈溢出解决方案都提供信任服务器证书,这意味着跳过 public 密钥验证
这是我的代码:
String connectionString = "jdbc:mysql://abcd-efg.rds.amazonaws.com:3306/test?trustServerCertificate=false&useSSL=true&requireSSL=true&verifyServerCertificate=true"
File f = new File("C:\temp\amazonPublic.pem");
CertificateFactory fact = null;
fact = CertificateFactory.getInstance("X.509");
X509Certificate cer = (X509Certificate) fact.generateCertificate(new FileInputStream(f));
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
char[] password = new char[] {'1','2','3','4'};
ks.load(null, password);
ks.setCertificateEntry("alias", cer);
FileOutputStream fos = new FileOutputStream(new File("C:\temp\ca.cer"));
ks.store(fos, password);
fos.close();
Properties p = new Properties();
p.setProperty("javax.net.ssl.trustStore","C:\temp\ca.cer");
p.setProperty("javax.net.ssl.trustStorePassword","1234");
try (java.sql.Connection connection =
DriverManager.getConnection(connectionString,p)) {
connection.isValid(1000);
}
这是错误:
Caused by: java.sql.SQLException: Could not connect to yyyyy-zz-prd-xxxxxxxxxxxx-1.rds.amazonaws.com:3306: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:706)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:406)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1022)
at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:483)
at org.mariadb.jdbc.Driver.connect(Driver.java:106)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 23 more
我在解决方案中遗漏了什么?
在使用 MariaDB 驱动程序时为了人类的利益 - 对其进行调试
我发现:
属性 应该是 "serverSslCert"
或 "trustStore"
只有在使用 System.setProperty
时才需要 javax.net.ssl
的前缀
所以这个简单的改变就成功了。
Properties p = new Properties();
p.setProperty("serverSslCert","C:/temp/amazonPublic.pem");
p.setProperty("trustStorePassword",jdbcDetails.getSensitiveData());
p.setProperty("user",jdbcDetails.username);
p.setProperty("password",jdbcDetails.getSensitiveData());
我想允许来自 java 客户端的连接。
此 Java 客户端需要为不同的数据库支持多个 public 密钥。
我必须使用 PUBLIC KEY
并且不能信任服务器证书。
我在网上搜索过,但找不到这个问题的完整解决方案,这些是我阅读过的一些链接:
first
third
我也读过这个 link 我的问题不是重复的,因为它是一个完全不同的连接类型 - 这是一个与连接管理器的 JDBC 连接,而不是一般的 URL 连接使用 SSL。
还有很多,我发现的所有堆栈溢出解决方案都提供信任服务器证书,这意味着跳过 public 密钥验证
这是我的代码:
String connectionString = "jdbc:mysql://abcd-efg.rds.amazonaws.com:3306/test?trustServerCertificate=false&useSSL=true&requireSSL=true&verifyServerCertificate=true"
File f = new File("C:\temp\amazonPublic.pem");
CertificateFactory fact = null;
fact = CertificateFactory.getInstance("X.509");
X509Certificate cer = (X509Certificate) fact.generateCertificate(new FileInputStream(f));
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
char[] password = new char[] {'1','2','3','4'};
ks.load(null, password);
ks.setCertificateEntry("alias", cer);
FileOutputStream fos = new FileOutputStream(new File("C:\temp\ca.cer"));
ks.store(fos, password);
fos.close();
Properties p = new Properties();
p.setProperty("javax.net.ssl.trustStore","C:\temp\ca.cer");
p.setProperty("javax.net.ssl.trustStorePassword","1234");
try (java.sql.Connection connection =
DriverManager.getConnection(connectionString,p)) {
connection.isValid(1000);
}
这是错误:
Caused by: java.sql.SQLException: Could not connect to yyyyy-zz-prd-xxxxxxxxxxxx-1.rds.amazonaws.com:3306: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:706)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:406)
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1022)
at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:483)
at org.mariadb.jdbc.Driver.connect(Driver.java:106)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 23 more
我在解决方案中遗漏了什么?
在使用 MariaDB 驱动程序时为了人类的利益 - 对其进行调试
我发现:
属性 应该是 "serverSslCert"
或 "trustStore"
只有在使用 System.setProperty
javax.net.ssl
的前缀
所以这个简单的改变就成功了。
Properties p = new Properties();
p.setProperty("serverSslCert","C:/temp/amazonPublic.pem");
p.setProperty("trustStorePassword",jdbcDetails.getSensitiveData());
p.setProperty("user",jdbcDetails.username);
p.setProperty("password",jdbcDetails.getSensitiveData());