programing

지정된 인증서를 사용한 Java MySQL SSL 연결

megabox 2023. 10. 26. 20:55
반응형

지정된 인증서를 사용한 Java MySQL SSL 연결

저는 jdbc(Connector/J)를 사용하여 SSL 암호화를 사용하여 mariadb 데이터베이스에 연결하는 자바 어플리케이션을 만들려고 합니다.서버에서 사용하도록 구성된 자체 서명 인증서를 이미 만들었습니다.연결을 시도하면 인증서가 자체 서명되어 있고 Java 트러스트 스토어에 추가되지 않아 인증서가 신뢰되지 않아 예외가 발생합니다.트러스트스토어를 수정하거나 응용 프로그램에 다른 트러스트스토어를 사용하고 싶기 때문에 jdbc만 신뢰할 수 있는 방법을 검색하여 "https://mariadb.com/kb/en/library/using-tlsssl-with-mariadb-connectorj/ 인증서 직접 제공"을 찾았습니다.

이제 연결을 시도하면 다음과 같습니다.

DriverManager.getConnection("jdbc:mysql://<hostname>:3306/<database>?useSSL=true&requireSSL=true&serverSslCert=/tmp/ssl/server-cert.pem", "<username>", "<password>");

serverSlCert 매개 변수를 다시 사용하지 않기 전에 이미 받은 예외가 있습니다.

Exception in thread "main" 

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 136 milliseconds ago.  The last packet sent successfully to the server was 129 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
    at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:203)
    at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4901)
    at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1659)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1226)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2188)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2219)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2014)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:776)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:386)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)
    at gymcash.server.mysql.DriverWrapper.connect(DriverWrapper.java:22)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at gymcash.server.mysql.MySQL.connect(MySQL.java:48)
    at gymcash.server.mysql.MySQL.connect(MySQL.java:52)
    at gymcash.server.main.Main.main(Main.java:25)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1964)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
    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 com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:188)
    ... 21 more
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
    at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:304)
    at 

sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:992)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
    ... 29 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:154)
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
    at com.mysql.jdbc.ExportControlled$X509TrustManagerWrapper.checkServerTrusted(ExportControlled.java:297)
    ... 31 more

파일이 존재하고 경로가 절대적이며 서버에서 사용하는 것과 동일하기 때문에 제가 무엇을 잘못하고 있는지 이해할 수 없습니다.누가 제가 뭘 잘못하고 있는지 말해주실 수 있나요?

Java 8, mysql-connector-java-5.1.45를 사용하고 있습니다.

몇 가지 방법이 있습니다.본인이 서명한 인증서 또는 인증서에 서명하는 데 사용한 인증 기관을 연결하는 데 사용하는 JVM에서 사용하는 기본 자바 키 저장소에 입력합니다.그러기 위해서는 키 도구를 사용해야 합니다.그러나 엔터프라이즈 VM 패키지를 관리하지 않는 한 보안 패키지의 기본 키 저장소를 가로채고 싶지 않을 수 있습니다.

먼저 키 툴이 어떻게 작동하는지 이해해야 합니다.

[자바 키 도구 명령][1]https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html

문제는 기본 키 저장소에 액세스할 수 없고 사용 중인 인증서 형식을 허용하지 않을 수 있다는 것입니다.자격증을 변환하고 지원되는 암호 알고리즘과 일치시키기 위해 일부 체육관 작업이 필요합니다.

일반적으로 기업을 관리하지 않는 한 단순한 작업을 수행하는 것이 더 낫습니다.

  1. 새 키 저장소 파일 생성
  2. 인증서를 이 키 저장소(또는 인증서 체인)로 가져옵니다.
  3. 신뢰할 수 있는 것으로 표시해야 합니다.
  4. 실행 시 -D 옵션을 사용하여 키 저장소를 프로그램에 전달합니다.

보통 DB에 연결하기 전에 코드에 이것을 추가하고 속성을 설정합니다.

if (DB_SSL || SSL) {
            System.setProperty("javax.net.ssl.keyStore", KEYSTORE);
            System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASS);
            System.setProperty("javax.net.ssl.trustStore", KEYSTORE);
            System.setProperty("javax.net.ssl.trustStorePassword", KEYSTORE_PASS);
        if (DEBUG_OPTION) {
            System.setProperty("javax.net.debug", "true");
        }
    }

private static String KEYSTORE = "/home/me/.keystore";
private static String KEYSTORE_PASS = "changeit";

언급URL : https://stackoverflow.com/questions/52244946/java-mysql-ssl-connection-with-specified-cert

반응형