[Tips] 간단한 SSL Client/Server 작성 테스트
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 !!" 메시지가 정상적으로 출력됨을 확인할 수 있습니다.