프로그래밍 언어/JAVA

[Tips] 간단한 SSL Client/Server 작성 테스트

투칼론 2023. 1. 26. 18:45
반응형

Windows 환경에서 Java 기반의 SSL Client/SSL 동작을 위해 간단한 프로그램과 옵션을 정리합니다. WAS를 사용 시에도 기본적으로 Java 레벨에서 필요한 작업을 사전 인지하고 있을 필요가 있습니다.

 

Java 기반에서는 openssl도 사용할 수 있지만, %JAVA_HOME%\bin 에서 제공되는 keytool 유틸리티를 유용하게 사용합니다.

 

 

1. Server 프로그램 작성

1) 소스 작성

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
 
public class EchoSSLServer {

    public static void main(String[] arstring) {

        try {
            SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            // 포트 9999로 서버 소켓 생성
            SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
            
            // 소켓 accept
            SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

            InputStream inputstream = sslsocket.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

            String rcvdata = null;
 
            // 클라이언트로부터 전송된 데이터를 읽어서 출력함
            while ((rcvdata = bufferedreader.readLine()) != null) {
                System.out.println(rcvdata);
                System.out.flush();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

 

2) 서버 인증서(테스트용) 작성

 

SSL 프로토콜에서 필요한 서버 인증서를 작성합니다. 보통 운영시스템에서는 외부 인증서업체에서 유료로 발급받습니다. 여기에서는 간단한 테스트용으로 사용하기 위한 자체서명(self-signed) 서버 인증서입니다.

 

사용방법)

keytool -genkey -keystore myKeystore -keyalg RSA

위에서 myKeyStore는 Key Store 이름이고, RSA는 키 알고리즘

아래와 같은 입력값을 요구합니다. 저는 KeyStore와 Private Key 비밀번호를 모두  weblogic으로 입력하여 생성하였습니다.

3) 서버 프로그램 실행

java -Djavax.net.ssl.keyStore=myKeystore -Djavax.net.ssl.keyStorePassword=weblogic EchoSSLServer​

 

2. Client 프로그램 작성

1) 소스 작성

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

public class EchoSSLClient {

public static void main(String[] arstring) {
    try {

        SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        // 클라이언트 소켓 생성 (포트는 서버와 연결하기 위해 9999)
        SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", 9999);

        OutputStream outputstream = sslsocket.getOutputStream();
        OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
        BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);

        // 서버로 "hello world !!" 데이터 전송
        String senddata = "hello world !!";
        bufferedwriter.write(senddata + '\n');
        bufferedwriter.flush();
        
    } catch (Exception exception) {
        exception.printStackTrace();
    }
  }
}

 

2) 서버 인증서에 대한 CA  업데이트

이 작업은 클라이언트에서 서버 인증서를 신뢰할만한 인증서인지 인증서 발급 인증기관(CA, Certificate Authority)을 Java의 cacerts 파일에 등록합니다. 

 

* 서버 인증서에서 CA 정보를 추출

keytool -export -keystore myKeystore -alias mykey -file server.cer -storepass weblogic

 

* 추출한 CA 정보를 자바 cacerts 파일에 정보 추가

keytool -import -alias myappcert -file server.cer  -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -storepass changeit

 

* alias 가 cacerts에 추가되었는지 확인함 (기존 ROOT CA로 알려진 verisign, comodo 등 기 등록되어 있음을 확인할 수 있음)

keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"  -storepass changeit

......
verisignuniversalrootca [jdk], 2016. 8. 26, trustedCertEntry, 
인증서 지문(SHA-256): 23:99:56:11:27:A5:71:25:DE:8C:EF:EA:61:0D:DF:2F:A0:78:B5:C8:06:7F:4E:82:82:90:BF:B8:60:E8:4B:3C
......
comodorsaca [jdk], 2016. 8. 26, trustedCertEntry, 
인증서 지문(SHA-256): 52:F0:E1:C4:E5:8E:C6:29:29:1B:60:31:7F:07:46:71:B8:5D:7E:A8:0D:5B:07:27:34:63:53:4B:32:B4:02:34
......
myappcert, 2022. 12. 21, trustedCertEntry, 
인증서 지문(SHA-256): C7:CC:D4:C7:35:13:7F:4C:FB:BA:0D:75:40:3F:8C:09:99:E7:B8:3A:9D:37:60:41:61:90:D5:BF:E0:4F:8B:D1
......

 

3) 클라이언트 실행

java  EchoSSLClient

 

서버 쪽에 "hello world !!" 메시지가 정상적으로 출력됨을 확인할 수 있습니다.

 

[글참조] http://://blueyikim.tistory.com/2528