Apache MINA와 WebSocket으로 SSL통신하기
카테고리: Java + Kotlin
Apache MINA
Apache MINA는 Java에서 흔히 쓰는 비동기 쓰레드 방식의 Server이다.
이전에 작성했던 포스팅에 이어서 작성한다.
https://syudal.github.io/post/Apache-MINA와-WebSocket으로-통신하기/
해결 방법
대부분의 사이트에서 HTTPS가 강제됨에 따라, 일반 웹소켓 요소(ws://)가 들어가 있으면 ERR_SSL_PROTOCOL_ERROR 오류를 출력하며 연결을 거부 한다.
이를 해결하는 방법은 두가지인데,
- 페이지에서 HTTPS를 제거하는 방법
- 웹 소켓에 SSL(wss://)을 구현하는 방법
1번 방법은 시대의 흐름을 역행하는 것이니 사용하지 않도록 하고, 2번 방법을 사용하고자 했는데 아무리 구글링을 해봐도 Apache MINA + WebSocket + SSL은 없었다.
따라서 만들 수 밖에 없었는데 참고한 레퍼런스는 아래와 같다.
https://mina.apache.org/mina-project/userguide/ch11-ssl-filter/ch11-ssl-filter.html
위와 같은 방식으로서 구현되어 있기에, 이를 MINA Project의 Repo중 하나인 FTP Server에서 가져왔다.
https://github.com/syudal/Apache-Mina-IoFilter-WebSocket
SslConfigurationFactory sslConfig = new SslConfigurationFactory();
sslConfig.setKeystoreFile(new File(Constant.SSLLocation));
sslConfig.setKeystorePassword(Constant.SSLPassword);
sslConfig.createSslConfiguration();
SslConfiguration ssl = sslConfig.createSslConfiguration();
SslFilter sslFilter;
try {
sslFilter = new SslFilter(ssl.getSSLContext());
} catch (GeneralSecurityException e) {
throw new IOException("SSL could not be initialized, check configuration");
}
if (ssl.getClientAuth() == ClientAuth.NEED) {
sslFilter.setNeedClientAuth(true);
} else if (ssl.getClientAuth() == ClientAuth.WANT) {
sslFilter.setWantClientAuth(true);
}
if (ssl.getEnabledCipherSuites() != null) {
sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
}
acceptor.getFilterChain().addFirst("sslFilter", sslFilter);
위와 같이 FilterChain에 sslFilter를 추가하는 것 만으로 ssl기능을 사용 할 수 있다.
※ KeystoreFile은 .jks를 추천하는데 테스트 하려면 아래의 게시글은 Apache FTP Server라고 작성되어 있지만, 방법은 같으니 읽어보는 것을 추천한다.
https://syudal.github.io/post/Apache-FTP-Server에-TLS-인증서-적용하기/