Spring Boot
로 만든 애플리케이션에 SSL
인증서를 적용해야하는 이슈가 생겼습니다. 이번 포스팅에서는 PEM
형식의 SSL
인증서를 적용하는 방법에 대해 포스팅하겠습니다.
localhost
환경에서 테스트 하기 위해 localhost에 인증서를 발급했습니다.
설치 URL은 리눅스, 윈도우 별로 설치하시면 됩니다.
다음 명령을 사용하여 localhost
도메인을 사용하는 SSL 인증서와 개인 키를 생성합니다
$openssl req -x509 -out localhost.pem -keyout localhost-key.pem -newkey rsa:2048 -nodes -sha256 -days 365 -subj "/CN=localhost"
생성된 인증서 및 개인 키를 확인하려면 다음 명령을 사용합니다
$openssl x509 -noout -text -in localhost.pem
$openssl rsa -noout -text -in localhost-key.pem
제가 했던 삽질이 도움이 될까 공유합니다.
첫 시도는 PEM
파일을 Keysotre에 적용하는 것이었습니다.
GPT도 그렇고 구글링도 그렇고 다들 이런 방식으로 알려주더군요.
# SSL Configuration
server:
port: 8443
ssl:
enabled: true
key-store: classpath:localhost.pem
key-store-password: Password
key-store-type: PEM
key-alias: tomcat
결과, 아래와 같은 오류가 발생했습니다.
Failed to load keystore type [PEM] with path [file:/Project/target/classes/localhost.pem] due to [PEM not found]
GPT가 말해놓고 답변하길...
Spring Boot는 기본적으로 Java 키 저장소 형식 (JKS)의 인증서를 지원하며 PEM 형식의 인증서를 직접 로드하는 기능은 제공하지 않습니다. 따라서 server.ssl.key-store-type를 "PEM"으로 설정하면 "PEM not found"와 같은 오류가 발생합니다.
GPT가 말하는 두가지 대안이 있습니다.
우선 JKS 형식으로 변환하는 방식으로 실행합니다.
=> 결론: 괜히 PEM 파일 손상시키지 말자
특정 Java 버전에는 최신 OpenSSL의 기본 암호 및 비밀번호 해시 알고리즘에 문제가 있는 것 같습니다.
OpenSSL에 다음 매개변수를 추가하여 문제를 해결했습니다. -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -macalg sha1
openssl pkcs12 -export -in '.\server.cer' -inkey .\server.key -out .\server.merged.pfx -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -macalg sha1
$ openssl pkcs12 -export -out localhost.p12 -inkey localhost-key.pem -in localhost.pem
$ keytool -importkeystore -srckeystore localhost.p12 -destkeystore localhost.jks -srcstoretype PKCS12
keytool 오류: java.io.IOException: parseAlgParameters failed: ObjectIdentifier() -- data isn't an object ID (tag = 48)
What the...
그밖에도 수많은 오류가 있어 패스
Bouncy Castle 라이브러리 사용 SSL Configuration
정의합니다.
GPT가 추천해준 두번째 라이브러리 Import 방식으로 진행했습니다.
먼저 Spring Boot 프로젝트에 Bouncy Castle 라이브러리를 추가해야 합니다. Maven을 사용하는 경우, pom.xml 파일에 다음 종속성을 추가합니다
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version> <!-- 현재 버전을 업데이트하세요 -->
</dependency>
그 뒤 Pem파일 읽는 코드를 작성하는데, PEMParser
, PEMKeyPair
등 클래스를 찾을 수 없었습니다.
public class PemFileReader {
public static KeyPair readPemFile(String pemFilePath) throws Exception {
try (FileReader fileReader = new FileReader(pemFilePath);
PemReader pemReader = new PemReader(fileReader)) {
PemObject pemObject = pemReader.readPemObject();
PEMParser pemParser = new PEMParser(pemObject.getContent());
PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
return converter.getKeyPair(pemKeyPair);
}
}
}
resources
폴더 아래 public-key
및 private-key
를 두고, 경로를 classpath
로 설정합니다.
# SSL Configuration
server:
port: 8443
ssl:
enabled: true
certificate: classpath:pem/localhost.pem
certificate-private-key: classpath:pem/localhost-key.pem
certificate
옵션을 이용하면 PEM
파일을 바로 적용할 수 있습니다.
이번 포스팅에서는 Spring Boot 에 PEM 형식의 SSL 인증서를 적용하는 방법에 대해 알아보았습니다.