728x90
반응형
SMALL
Netty를 이용하여 TCP Server를 개발하고 있다.
정해진 프로토콜에 맞게 통신하고 데이터 일부는 파일로 저장하고 저장된 파일을 분석하는 모듈이다.
프로토타입의 개발이 완료되는 시점에 암호화 통신이 필요하다는 요구사항이 추가 되었다.
Netty는 아주 쉽게 이를 처리할 수 있다.
Netty의 구조를 잘 생각해 보면 pipeline 에 ssl 통신처리 handler 를 넣어주면 되지 않을까? 생각이 든다.
일단 인증서를 만들어 보자.
java 의 keytool 을 이용해 만들수 있고 sign 알고리즘은 SHA256withRSA 를 이용하도록 했다.
keytool -genkey -v -keystore server.jks -alias server_private -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 365
test용 client 에도 적용해야 하니 client.jks 파일도 만들자.
keytool -genkey -v -keystore client.jks -alias client_private -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 365
csr을 keytool 로 생성한다.
keytool -export -alias server_private -keystore server.jks -rfc -file trustServer.cer
keytool -export -alias server_private -keystore client.jks -rfc -file trustClient.cer
server.jks 에 trustClient.cer 을, client.jks 에 trustServer.cer를 import 해 준다.
keytool -import -alias trustClient -file trustClient.cer -keystore server.jks
keytool -import -alias trustServer -file trustServer.cer -keystore client.jks
준비 끝
이제 channel init 할 때 io.netty.handler.ssl.SslContext 를 pipline 에 넣어주기만 하면 된다.
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if (prop.isUseSsl()) {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(ResourceUtils.getFile("classpath:server.jks")), "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
SslContext sslCtx = SslContextBuilder.forServer(kmf).build();
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
}
pipeline.addLast(stringEncoder);
pipeline.addLast(new FileSaveHandler(prop, scheduler));
}
Client 에서는
KeyStore ks = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream("D:\\certificate\\client.jks");
ks.load(is, "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext sslcontext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
sslcontext.init(null, trustManagers, new SecureRandom());
factory = sslcontext.getSocketFactory();
...
sslSocket = (SSLSocket) factory.createSocket(socket, null, PORT, false);
sslSocket.setEnabledCipherSuites(factory.getSupportedCipherSuites());
...
OutputStream os = sslSocket.getOutputStream();
os.write(buffer, 0. readBytes);
os.flush();
...
잘된다.
netty를 사용하면
pipline 에 handler 를 추가하고 필요시 decoder, encoder를 추가하면서
복잡한 raw level의 socket 과 관련된 처리는 신경쓸 필요 없이
필요한 business logic 에 집중할 수 있어서 좋다.
728x90
반응형
LIST
'IT > JAVA' 카테고리의 다른 글
Java ProcessBuilder cd 로 이동 (0) | 2021.07.23 |
---|---|
EventSource IE 처리 (Feat. Polyfill) (0) | 2021.05.07 |
Netty(5) - TCP/IP 파일 송수신 (0) | 2021.02.09 |
Netty(4) - encoder/decoder 기본 (0) | 2021.02.09 |
Netty(3) - Byte array 로 받기 - ByteArrayDecoder is not a @Sharable handler (0) | 2021.02.05 |