정리하게 된 배경 스토리
프로젝트에서 Let’s Encrypt 인증서가 자동 갱신되지 않는 현상이 있었습니다. 이를 해결하기 위한 공부 과정에서 알게된 내용들을 두개의 포스트로 나누어 정리하게 되었습니다. 이 포스트는 이중 첫번째 포스트로 인증서가 무엇인지, Let’s Encrypt와 작동 원리를 다룹니다.
인증서란?
인증서는 공개키와 공개키의 소유자를 연결해주는 전자문서로, 클라이언트가 접속한 서버가 신뢰할 수 있는 서버임을 보장하기 위해 사용한다.
인증서는 개인이 발급받아 개인의 신원을 식별하기 위해서도 사용한다. 과거에 인터넷 뱅킹을 이용하기 위해 사용하던 공인인증서가 바로 그것이다.
인증서의 작동 원리를 이해하기 위해서는 공개키 기반 구조(PKI,Public Key Infrastructure)와 전자서명 기술을 이해해야 한다. 전자서명 기술은 비대칭 암호화와 (암호학적)해시를 이해해야 한다.
공개키 기반 구조(PKI,Public Key Infrastructure)
메시지의 암호화 및 전자 서명을 제공하는 복합적인 보안 시스템 환경을 말한다.
현실에는 개인의 신원을 파악하기 위해 사용되는 신분증과, 신분증을 발급하고 유효성을 검증해주는 주민센터등의 관청이 있다.
인증서도 신분증과 마찬가지로 인증서를 발급하고, 인증서를 검증해주는 기관이 필요하다. 이런 기관을 CA 라고 한다. 한단계 더 나아가서 CA 는 어떻게 신뢰할 수 있을까?
계층형 CA
CA는 계층구조를 가진다. 하위의 CA는 상위의 CA가 인증해주고, 상위의 CA는 더 상위의 CA가 인증해주는 방식이다.
계층형 CA 예시
이런 계층 구조는 재귀함수 처럼 끝도 없이 이어질 수는 없는 노릇이니 최상위의 CA 즉, RootCA라는 개념이 필요하다. RootCA 는 자기 자신이 스스로를 인증한다. 이게 대체 무슨 소린가 싶겠지만, RootCA 를 보증하는 기관은 보통 각 국가의 정부다.
전자서명
전자서명은 어떤 전자문서에 서명하였음을 나타내기 위해 전자문서에 첨부되거나 논리적으로 결합된 전자적 형태의 정보를 말한다.
즉, 워드파일, 한글파일 등의 파일의 작성자가 특정 사람(기업)임을 보장하기 위한 정보를 전자서명이라 한다.
비대칭 암호화와 해시
비대칭 암호화
비대칭 암호화는 하나의 키로 암호화된 데이터는 이와 쌍을 이루는 다른 키로만 복호화 할 수 있는 방식의 암호화를 말한다. 키 하나는 키의 소유자만 볼 수 있도록 숨겨두고, 나머지 하나의 키는 공개해 모두가 볼 수 있도록 하여 기밀성과 부인방지를 모두 구현한다.
해시
해시는 본래 탐색을 빨리 하기 위해 고안된 것이나, 입력값의 단 1비트만 변경되어도 해시함수를 통해 생성된 해시값이 전혀 다르다는 점에서 데이터의 무결성을 보증하기 위해 사용한다.
전자서명의 원리
전자서명은 파일의 해시값을 비밀키로 암호화 해(이렇게 만든 것을 서명이라 한다.) 파일과 함께 건내주면, 건네받은 쪽에서 파일의 해시값과 서명을 공개키로 복호화해 비교하는 방식으로 무결성을 보증한다. 만약 파일이 변조되었다면 해시값과 서명의 복호화 값이 달라 탐지할 수 있다.
전자서명 원리
인증서
서버의 각종 정보를 CA가 자신의 비밀키로 서명을 생성해 공개키와 함께 제공하는 것.
인증서에는 발급 대상, 발급 기관(CA), 유효기간, 지문(서명)
구글의 인증서
HTTPS
TLS 라는 보안 프로토콜 위에서 동작하는 HTTP. TLS 는 위에서 말한 인증서를 이용해 연결을 암호화 하는 프로토콜이다. SSL을 계승한 것이지만 일반적으로 SSL 이라 불린다.
브라우저에서 주소창 옆에 자물쇠를 누르면 인증서 정보를 볼 수 있다.
Let’s Encrypt
무료로 인증서를 발급해주는 비영리 기관
유효기간이 3달이라는 단점이 있지만, 무료이고, certbot을 통해 자동으로 인증서를 갱신할 수 있으니 큰 문제는 아니다.
동작 원리
Let’s Encrypt가 인증서를 발급하려면 당연히 발급을 요청한 주체(이하 주체)가 해당 도메인의 관리자임을 증명해야 한다. 이를 위해 Let’s Encrypt 는 주체에게 어떤 작업 수행을 요청한다. 이때 요청되는 작업에는 대표적으로 아래 3가지가 있다.
•
웹서버의 특정 경로에 접근할 수 있는지를 확인한다.
•
DNS 레코드에 접근할 수 있는지를 확인한다.
•
주체의 시스템에서 웹서버를 동작시키고, 도메인을 통해 그 웹서버에 접근할 수 있는지를 확인한다.
이 작업들을 정상 수행할 수 있다는 것을 CA(Let’s Encrypt)가 검증하면 인증서를 생성하기 위한 키를 발급하고, 이를 통해 인증서를 생성한다.
certbot
Let’s Encrypt 인증서를 더 쉽게 발급할 수 있도록 제작된 오픈소스 툴이다.
standalone
자체 웹서버를 구동해 이를 이용해 인증서를 발행한다. 동작원리에서 세번째 작업에 해당한다. 80포트를 사용할 수 있어야 한다. 즉, 80포트를 사용하는 다른 웹서버가 있으면 안된다는 것이다. 나아가, aws 설정 등에서 80 포트를 내부의 다른 포트로 포트포워딩 하거나 하는 것도 안된다.
webroot
현재 동작하고 있는 웹서버가 있을 경우 웹의 root 경로에 임시 파일을 생성하는 작업을 통해 인증서를 발급한다. 동작원리에서 첫번째 작업에 해당한다.
renew
인증서를 재발급 하는 요청이다. 기존에 발급받은 도메인에 대한 인증서를 갱신할 때 사용한다.
Spring Boot 프로젝트에 인증서를 적용하는 방법
Spring Boot 에서는 기본적으로 tomcat 을 사용한다. 따라서 tomcat 이 인증서를 인식할 수 있도록 certbot이 만든 인증서를 pkcs12로 변환해야 한다. 또한 이렇게 변환된 인증서의 경로를 application.yml 등에 지정해야 한다.
인증서 변환
openssl pkcs12 -export -inkey privkey.pem -in fullchain.pem -out test.p12 -name tomcat
Shell
복사
openssl을 이용해 .pem 인증서를 pkcs12 로 변환한다.
application.yml 설정
server:
port: 10443
ssl:
key-store: file:test.p12
key-store-type: PKCS12
key-store-password: "비밀번호"
YAML
복사
key-store: file:test.p12 는 빌드된 jar 파일의 위치를 기준으로 상대경로로 인증서의 위치를 지정한다.
다음 포스트 예고
다음 포스트에선 이런 지식들을 바탕으로 Let’s Encrypt 인증서가 문제없이 자동 갱신되도록 하는 과정에 대해 다뤄볼 것입니다.