Development Logs/Spring Ecosystem

[Spring GW] Netty HttpClient TLS버전 추가 설정 기능 테스트 (TLSv1만 연결가능한 서버 구현하기)

유뱅유뱅뱅 2024. 11. 17. 12:16

2024.11.17 - [Development Logs] - [Spring GW] Netty HttpClient TLS 버전 추가 설정


 

[Spring GW] Netty HttpClient TLS 버전 추가 설정

더보기Java17 버전을 이용해, Spring Cloud GW로 내재화 개발을 진행하다가, Provider서버 중 TLSv1 Protocol 만 연결 가능한 케이스가 있어 문제가 발생하였고, 이를 해결하기위해 쓴 글입니다. JVM의 HTTPS 설

yubh1017.tistory.com

위와 연결되는 글입니다.

더보기

Spring Cloud GW로 내재화 개발을 진행하다가 아래의 테스트 History 과정을 겪고 TLSv1만 연결가능한 로컬 서버를 구현하여, Spring GW의 테스트코드로 확인한 과정에 대한 글입니다.

 

테스트 History

시도1. MockWebServer 테스트를 진행했으나, MockWebServer의 TLS 버전 Protocol 변경이 불가하였음
시도2. 운영기에서 TLSv1을 제공하여 문제 있었던 Provider의 개발기 서버를 확인하였으나, TLSv1.3을 제공하고 있어 확인이 불가능 하였음
시도3. TLSv1만 연결가능한 로컬 서버를 구현하여, Spring GW의 테스트코드로 확인
- 최종적으로 확인 완료


1. TLSv1만 연결가능한 로컬 서버 구현

1) 간단한 Spring Boot 서버 구현

@SpringBootApplication
public class TlSv1MockServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TlSv1MockServerApplication.class, args);
    }

    @RestController
    @RequestMapping("/api")
    class HelloController {
        @GetMapping("/hello")
        public String sayHello() {
            return "Hello, TLSv1!";
        }
    }
}

 

2) 자체 서명된 인증서 생성 및 application.properties 설정

자체 서명된 인증서 생성

  • 자체 서명된 인증서
    • Test를 위해 임시로 사용
  • PKCS12
    • PKCS12는 Public Key Cryptographic Standards의 준말로 Password로 보호된 형식으로써, 여러 인증서 및 키를 포함할 수 있습니다. Java뿐만 아니라 여러 플랫폼에서 사용이 가능합니다.
  • resource에 아래 명령어 쳐서 PKCS12 생성
keytool -genkeypair -alias {test} -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650

application.properties 설정

  • https 적용
  • PKCS12 파일이 resource 하위에 있어야 아래 key-store 위치가 적용됨
spring.application.name=TLSv1MockServer
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:{your fileName}
server.ssl.key-store-password={your password}
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=leviathan
server.ssl.enabled-protocols=TLSv1 // {your protocol}

 

3) java.security 수정

 

Java Security Property 수정

더보기Java17 버전의 amazon-corretto-17.jdk 를 사용하고 있었는데, Java Security Property 중 jdk.tls.disabledAlgorithms 를 확인해보면, 기본적으로 TLSv1.2 하위의 암호화 알고리즘을 disabledAlgorithms 에 포함되어

yubh1017.tistory.com

 

 

4) curl로 https 및 TLS 버전이 적용됬는지 확인

  • TLSv1.1 이하는 Postman 또는 Chrome으로 확인이 불가능할 수 있음(해당 버전 지원 X)
curl -vk --tlsv1 https://localhost:8443/api/hello

 

tlsv1로 요청

 

tlsv1.1로 요청

 

2. Spring Cloud GW의 테스트코드로 로컬에서 TLSv1만 제공하는 로컬 서버 테스트 결과

  • 테스트코드는 호출하는 코드 구현하면 되므로, 생략

Case1. Netty HttpClient의 support-protocols에 전체 다 지원하는 케이스(TLSv1 지원)

@TestPropertySource(properties = {
        "spring.cloud.gateway.httpclient.ssl.support-protocols[0]=TLSv1.3",
        "spring.cloud.gateway.httpclient.ssl.support-protocols[1]=TLSv1.2",
        "spring.cloud.gateway.httpclient.ssl.support-protocols[2]=TLSv1.1",
        "spring.cloud.gateway.httpclient.ssl.support-protocols[3]=TLSv1",
        "spring.cloud.gateway.httpclient.ssl.support-protocols[4]=SSLv3",
        "spring.cloud.gateway.httpclient.ssl.support-protocols[5]=SSLv2Hello",
        "logging.level.io.netty.handler.ssl=DEBUG",
//        "logging.level.reactor.netty=DEBUG"  
})
  • TLSv1만 제공하는 로컬서버(127.0.0.1:8443) https로 호출하였는데, handshake 과정의 Server Hello 과정에서 TLSv1만을 제공할것이므로, TLSv1 포함 여러 Protocol을 지원하도록 설정한 Netty HttpClient는 TLSv1으로 연결됨을 확인 가능함

 

Case2. Netty Http Client의 support-protocols에 TLSv1.2만 지원하는 케이스(TLSv1 지원X)

@TestPropertySource(properties = {
        "spring.cloud.gateway.httpclient.ssl.support-protocols[0]=TLSv1.2",
        "logging.level.io.netty.handler.ssl=DEBUG"
//        "logging.level.reactor.netty=DEBUG"
})
  • TLSv1만 제공하는 로컬서버(127.0.0.1:8443) https로 호출하였는데, handshake 과정의 Server Hello 과정에서 TLSv1만을 제공할것이므로, TLSv1.2 Protocol만을 지원하도록 설정한 Netty Http Client는 SSLHandshakeException 에러가 발생함 (500)