Java, SSL 통신 체크하기!

Develop/Java 2021.01.18 댓글 PSJco
728x90
반응형

안녕하세요, PSJ입니다. 

오늘은 업무 중에 운영서버에서 SSL 통신 여부를 확인할 필요가 있었습니다. 

 

보통 Linux 서버에서는 curl을 통해서 체크를 할 수 있습니다. 

$ curl -v https://www.naver.com

이렇게 "-v 옵션"을 통해서 SSL 통신에 사용하는 인증서를 확인할 수 도 있고요. 하지만, curl의 경우 OS 레벨의 SSL 통신은 체크 가능하지만, JAVA Application 레벨에 SSL 통신 체크할 수 없습니다. JAVA의 경우 별도 SSL 모듈을 사용하기 때문이죠. 

 

Java에서는 기본적으로 유효한 CA 인증기관의 인증서들을 cacerts라는 별도 키 저장소에 저장해 관리하고 있습니다. 일반적으로 대부분 CA(중계기관) 인증서를 포함하고 있습니다.

 

하지만, 제 업무환경은 내부망에 SSL 통신을 모니터링하는 솔루션을 사용하고 있습니다. SSL 통신 시 인증서를 가로채서 솔루션의 인증서로 바꿔서 통신하는 방식으로 동작하는 솔루션인데요. 해당 솔루션의 인증서는 사설 인증서이므로 당연히 유효한 중계기관 인증서가 아니라, SSL 통신 시 아래와 같은 오류가 발생하게 됩니다. 

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

 

먼저 curl 명령어에 "-v 옵션"을 통해서, 해당 시스템으로 통신하는데 사용하는 인증서를 체크해 봅니다. 

$ curl -kv https://www.naver.com

당연히, 내부 솔루션에 변조된 SSL 인증서로 통신이 이루어지고 있겠죠? 그렇다면 curl 자체도 실패하게 될 겁니다. 그럴 때는 "-k 옵션"을 추가해 주시면 인증서를 무시하고 통신할 수 있습니다. 

 

※ 사설 인증서를 Keytool 을 통해 등록해서 SSL 통신을 성공하는 부분은 다른 포스팅을 참고하시면 됩니다. 

2021/01/18 - [분류 전체보기] - Java, SSL 사설 인증서 등록하기!

 

Java, SSL 사설 인증서 등록하기!

안녕하세요, PSJ입니다. 오늘은 Java Application 개발 중 Server to Server 통신을 하는 경우가 간혹 있는데요. 이때 SSL(HTTPS) 통신을 하게 되는 경우도 많습니다. 일반적인 상황에 정상적인 인증서를 사용

www.psjco.com

자, 이제 Java 소스를 통해 특정 주소의 SSL 통신이 정상적으로 동작하는지 간단하게 체크하는 코드입니다. 

import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;

public class SSLChecker {
    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("Usage: "+SSLChecker.class.getName()+" <host> <port>");
            System.exit(1);
        }
        try {
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));

            SSLParameters sslparams = new SSLParameters();
            sslparams.setEndpointIdentificationAlgorithm("HTTPS");
            sslsocket.setSSLParameters(sslparams);

            InputStream in = sslsocket.getInputStream();
            OutputStream out = sslsocket.getOutputStream();
            
            out.write(1);

            while (in.available() > 0) {
                System.out.print(in.read());
            }
            System.out.println("Successfully connected");

        } catch (Exception exception) {
            exception.printStackTrace();
            System.exit(1);
        }
    }
}

SSLChecker.java
0.00MB

 

서버에 적당한 위치에 Java 소스를 올려두시거나, Local에서 Compile 후 Class 파일을 올리셔도 됩니다. (JDK가 없으면 Compile이 안 되겠죠) 

# JDK 설치 경로에서 Javac로 소스를 컴파일
$ /usr/java/jdk1.8.0/bin/javac SSLChecker.java

# 컴파일된 SSLChecker 실행해 SSL 통신체크 
$ java SSLChecker www.test.com 443 

# 통신 성공시 성공메시지 출력!
Successfully connected 

# 통신 실패시 오류메시지 출력! 
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
...
...
...

통신 실패시에는 오류 메시지 내용을 토대로 디버깅하시면 됩니다. 

 

이상입니다. 

 

GitHub - 4ndrej / SSLPoke.java 참조
728x90
반응형

댓글