我想允许来自java客户端的连接。
此 Java 客户端需要支持不同数据库的多个公钥。
我必须使用PUBLIC KEY
来执行此操作,并且不得信任服务器证书。
我已经在网上搜索过,但找不到这个问题的完整解决方案,这些是我读过的一些链接:
第一
第二
第三
我也读过这个链接myt问题不是重复的,因为它是一种完全不同的连接类型 - 这是与连接管理器的JDBC连接,而不是与SSL的通用URL连接。
还有更多,我发现的所有堆栈溢出解决方案都提供给信任服务器证书,这意味着跳过公钥验证
这是我的代码:
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"
javax.net.ssl
前缀仅在使用System.setProperty
时才需要
所以这个简单的改变就成功了。
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());