2020/02/20 - [IT/Spring] - Spring Boot HTTPS 설정 & WebClient HTTPS
이전 글에서 spring boot 에서 HTTPS 설정을 아주 쉽게 하는 방법을 작성했었다.
그런데 테스트 하다보니 재미있는(?) 현상이 발견 되었다.
바로 ssl 의 alias 에 대문자가 들어갈 경우 undertow 가 startup 은 잘 되는데 실제 API 호출 시
ssl handshake 오류가 발생하는 것이다.
지금 개발하고 있는 API 는 기존의 legacy 환경과 이미 서버 환경이 구성되어 있는 상태에서
즉, 이미 key sotre file 이 있는 상태에서 배포가 되어야 하는데
이전에 작성된 key store 의 alias 는 대문자였다.
openjdk bugs 를 보니 uppercase alias 를 handling 하지 못한다는 내용이 있네..
https://bugs.openjdk.java.net/browse/JDK-8166255
어떻게 해결 해야 할까
install.sh 를 통해 이전에 설치되어 있는 keystore 를 삭제하고 새로 생성해도 되지만 이건 해결방법이 아니다.
해결 방법은 너무... 허무하게 간단했다.
application.yaml 의 ssl 설정 내용에서 alias 를 빼는 것이다...
key-store-type 을 제거해도 잘 동작하니.. 이것도 제거
server:
servlet:
context-path: /linkage
port: 8082
ssl:
enabled: true
key-store: C:\\dev\\yhkim-server.ssl
key-store-password: 12341234
잘 된다.
그런데 key-store 와 key-store-password 가 application.yaml 파일에 plain-text 로 있는것이 영 마음에 들지 않는다.
Jasypt (Java Simplified Encryption)를 이용해서 쉽게 해결할 수 있다.
먼저 pom.xml 에 dependency를 추가 하고
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
암호화 / 복호화 해 본다.
StandardPBEStringEncryptor jasypt = new StandardPBEStringEncryptor();
jasypt.setPassword("unknown"); //암호화 키
jasypt.setAlgorithm("PBEWithMD5AndDES");
String encryptedText = jasypt.encrypt("C:\\dev\\yhkim-server.ssl");
String plainText = jasypt.decrypt(encryptedText);
System.out.println("encryptedText: " + encryptedText); //암호화된 값
System.out.println("plainText: " + plainText); //복호화된 값
key 를 다르게 설정했기 때문에 해독할 수 있는 녀석도 만들어 준다.
@Configuration
public class JasyptConfig {
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
return getEncryptor();
}
}
getEncryptor(); 는 위에서 암호화 한 내용과 동일한 내용을 담고 있으며 PooledPBEStringEncryptor를 반환한다. getEncryptor 메서드가 포함된 jar 는 난독화 하여 추가하도록 한다.
그리고 다시 application.yaml 파일로 돌아가서 암호화 해야 하는 설정값들을 ENC 로 감싸서 표현한다.
ssl:
enabled: true
key-store: ENC(Lx95Id99oLIIJGL6NkLVHtRl4cSuPQ4dDeCC1V3CFK17mjqtmVL3kDRWZIA6ej0NOHZ)
key-store-password: ENC(DA0g1D2IdoPA3fZOgyNpgKoyy2Q1ckLXNzfrz)
암호화 key의 경우 boot 실행 시 -Djasypt.encryptor.password=unknown... 식으로 실행시켜서 노출을 막을 수도 있다.