org.postgresql.util.PSQLException: SSL error: Received fatal alert: unexpected_message

postgresql数据库验证证书报错. 其实早就找到答案了, 可是因为不细心, 墨迹了一天 真是不识庐山真面目,只缘身在此山中。废话很少说,上过程java

代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class jdbcTest {

  public static void main(String[] args){
     /* String url = "jdbc:postgresql://192.168.1.202:5432/herodb?ssl=true&sslcert=E:\\certificate\\sysadmin.crt&sslkey=E:\\certificate\\sysadmin.key&sslrootcert=E:\\certificate\\ca.crt";
      String username = "sysadmin";
      String password = "";*/

    String url = "jdbc:postgresql://192.168.1.202:5432/herodb";

    Properties props = new Properties();
    props.setProperty("user","sysadmin");
    props.setProperty("sslmode","verify-ca");//确保链接加密,客户端信任服务器证书。
    props.setProperty("sslcert","E:\\certificate\\sysadmin.crt");
    props.setProperty("sslkey","E:\\certificate\\sysadmin.key");
    props.setProperty("sslrootcert","E:\\certificate\\ca.crt");
    props.setProperty("loggerLevel","TRACE");//调整日志级别,打印详细日志
    Connection conn = null;
    try {
      Class.forName("org.postgresql.Driver");
      //conn = DriverManager.getConnection(url, username, password);
      conn = DriverManager.getConnection(url, props);
    } catch (Exception e1) {
      e1.printStackTrace();
    }
    System.out.println(conn);
    try {
      conn.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }


}

日志:

八月 26, 2019 4:26:49 下午 org.postgresql.Driver connect
详细: Connecting with URL: jdbc:postgresql://192.168.1.202:5432/herodb
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection <init>
详细: PostgreSQL JDBC Driver /*$mvn.project.property.parsedversion.osgiversion$*/
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection setDefaultFetchSize
详细:   setDefaultFetchSize = 0
八月 26, 2019 4:26:49 下午 org.postgresql.jdbc.PgConnection setPrepareThreshold
详细:   setPrepareThreshold = 5
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl 
openConnectionImpl
详细: Trying to establish a protocol version 3 connection to 192.168.1.202:5432
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl 
openConnectionImpl
信息: Try connection 192.168.1.202:5432
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
很是详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
很是详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.Encoding <init>
很是详细: Creating new Encoding UTF-8 with fastASCIINumbers true
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
很是详细:  FE=> SSLRequest
八月 26, 2019 4:26:49 下午 org.postgresql.core.v3.ConnectionFactoryImpl enableSSL
很是详细:  <=BE SSLOk
八月 26, 2019 4:26:49 下午 org.postgresql.ssl.MakeSSL convert
详细: converting regular socket connection to ssl
八月 26, 2019 4:26:50 下午 org.postgresql.Driver connect
详细: Connection error: 
org.postgresql.util.PSQLException: SSL error: Received fatal alert: unexpected_message
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:42)
	at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:453)
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:76)
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:175)
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
	at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195)
	at org.postgresql.Driver.makeConnection(Driver.java:458)
	at org.postgresql.Driver.connect(Driver.java:260)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:208)
	at org.postgresql.test.ssl.jdbcTest.main(jdbcTest.java:35)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
	at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2038)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1135)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
	at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:40)
	... 10 more

缘由:

主要是openssl证书生成的 my.key 文件 是pem格式的,pgjdbc并无支持处理pem格式的key证书, 须要把它转换为der格式的证书git

解决方案:

用如下openssl命令去作证书转换github

openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -nocrypt -out my.key.der

参考:

github关于这个问题的讨论sql