Two-Way SSL
2024년 6월 27일정리
- SSL은 크게 3가지 기능을 제공한다
- 사이트 인증
- 데이터 기밀성 (데이터 보호)
- 메시지 무결성 (데이터 변경 x)
- SSL은 OSI 모델 기준 4(Transport)계층보다 ‘위’ 7(Application)계층 보다 ‘아래’에 위치하며 7계층의 HTTP, IMAP, FTP 등의 상위 프로토콜의 데이터를 보호해준다
- HTTP → HTTPS
- IMAP → IMAPS
- FTP → FTPS
- SSL 인증서
- 클라이언트와 서버 간 통신 안정을 보증해주는 문서
- 클라이언트가 접속한 서버가 신뢰할 수 있는 서버임을 보장
- SSL 통신에 사용할 공캐키를 클라이언트에 제공
- 도메인 이름, 발급 CA(Certificate authority), CA 서명, 유효기간, 공개키 등의 내용을 포함한다
- SSL은 공개키와 비밀키 방식을 혼합해서 사용한다
- ‘대칭키’를 사용하여 주고 받는 데이터를 암/복호화하는데 사용한다
- 위의 ‘대칭키’를 공유할 때 ‘비밀키’를 사용해서 공유한다
- 대칭키는 SSL handshake 과정 중 클라이언트와 서버가 랜덤으로 생성한다
- Diffie-Hellman 같은 방식으로 대칭키 생성
- 혹은 대칭키를 만들 재료 데이터를 공유
- 일반적인 SSL handshake의 상세한 설명은 다음을 참고
- 3 way handshake
- 클라이언트가 서버에 SSL 요청
- 서버가 클라이언트에 인증서(공개키, 서버 도메인 이름, 알고리즘 종류 등) 전달
- 클라이언트는 서버가 보낸 공개키가 있다면 인증서 서명을 검증하고 없다면 CA(인증 기관)에 요청해 공개키를 가져와 검증
- 인증서가 유효하다면 클라이언트에서 대칭키를 생성하여 공개키로 암호화하여 서버로 보낸다
- SSL 작동 방식에 따라 클라이언트가 대칭키를 만들 수도 있고 직접 키를 만드는게 아니라 키를 만들 재료를 주기도 한다
- 서버는 클라이언트로부터 받은 대칭키를 서버의 비밀키로 복호화하여 이 값을 가지고 데이터를 암/복호화한다
- Two-Way SSL handshake 순서
- 클라이언트가 보호 자원에 접근 요청
- 서버가 클라이언트에 인증서 제공
- 클라이언트는 서버의 인증서를 확인
- 인증이 성공한다면, 클라이언트는 서버에 인증서를 전달
- 서버는 클라이언트의 자격 증명 확인
- 자격 증명이 올바르다면, 서버는 클라이언트가 요청한 보호 자원에 대한 접근 권한
- Two-Way SSL 연결을 하기 위해서는 다음의 재료가 필요하다
- 비밀키
- 클라이언트 인증서
- 루트 인증서 (Root CA)
- 중간 인증서 (certificate authority intermediate certificates)
- One-Way handshake vs Two-Way handshake
- 일반적인 SSL handshake(One-Way handshake)는 클라이언트 쪽에서만 서버가 보낸 인증서를 확인한다 (= 클라이언트가 서버의 인증서를 검증)
- Two-Way handshake는 서버와 클라이언트 모두 각자 보낸 인증서를 확인한다 (= 클라이언트와 서버가 서로의 인증서를 검증
- 참고
- Two-Way handshake는 One-Way handshake와 비교하여 서버와 클라이언트 둘 다 서로의 증명서를 저장해야하는 단점이 있지만, 클라이언트 증명이 필요한(ex. 결제) 도메인에서 쓰인다
궁금증
- 매번 HTTPS 요청을 보낼 때마다 SSL 인증 혹은 handshake를 거쳐야하는가?
- HTTP는 단방향 통신이라 서버에 요청할 때마다 handshake 과정을 거쳐야하는데, 클라이언트가 HTTP를 끊기 전까지 연결 유지된다
- 언제 HTTP가 끊기는가?
- 네트워크 문제
- 클라이언트가 헤더에
Connection: close
를 명시 - timeout
- 언제 HTTP가 끊기는가?
- 헤더
Connection: keep-alive
로 HTTP 연결을 유지시킬 수 있다 → handshake 과정을 생략할 수 있다- keep-alive를 persistent connection이라고도 불리는 거 같다
- HTTP 1.1에서는 keep-alive를 헤더에 적지 않아도 기본적으로 keep-alive로 동작한다
- HTTP 2.0에서는 keep-alive를 사용하지 않는다
- HTTP 2.0은 multiplexing 기능으로 stream 형태로 데이터를 주고 받을 수 있어서 keep-alive 헤더가 필요없는 것으로 추측
- SSL 사용했을 때 데이터 암/복호화는 데이터 기밀성, 무결성을 위해 매번 진행되어야 하는 게 맞는 거 같다
- 매번 암/복호화를 하면 성능상의 이슈가 생기지 않을까 생각했는데 데이터 안전을 위해서라도 이 정도 감수는 해야한다고 생각한다
- SSL 처리를 도와주는 SSL 가속기가 있다
- 위키피디아의 정의를 보면 offloading processor라는 표현을 쓰는데 offloading이 뭐지?
- SSL 암/복호화, handshake 처리를 서버(was를 말하는 거 같음)가 아닌 앞단의 proxy나 하드웨어 장비에 맡기는 걸 offloading이라 한다
- SSL 가속기는 TCP offloading인데 CPU가 TCP/IP 관련된 처리를 다른 하드웨어에서 처리하도록 한다
- CPU offloading 단어도 있더라
- 이 때까지 SSL 가속기 구축이라던가 해당 용어를 잘본적이 없었는데 잘 쓰이지 않는건가?
- 처음에는 대규모 서비스에만 필요한 기술이 아닌가 싶었는데 가만 생각해보면 nginx가 HTTPS를 받고 복호화 뒤에 was로 보낸다 (= was에는 HTTPS 복호화 코드가 없다)
- Apache, Nginx 웹 서버가 기본적으로 TCP offloading과 유사한 역할을 한다
- HTTP는 단방향 통신이라 서버에 요청할 때마다 handshake 과정을 거쳐야하는데, 클라이언트가 HTTP를 끊기 전까지 연결 유지된다
- SSL handshake 할 때마다 서버에 대칭키(세션키)가 계속해서 쌓여서 용량 부족 사태가 발생할 수 있지 않을까?
-
nginx에 ssl_session_cache 문법으로 대칭키를 최대로 저장할 수 있는 용량을 설정할 수 있는 옵션이 있다
-
1MB 당 4000개의 키를 저장할 수 있다고 한다
-
default은 none 옵션으로 세션 키를 재사용할 수는 있지만 따로 세션 키를 저장하지 않는다
the use of a session cache is gently disallowed: nginx tells a client that sessions may be reused, but does not actually store session parameters in the cache
-
- 웹 브라우저에 CA 인증서와 공개키가 있다는 글을 봤는데, 해당 데이터 업데이트가 이루어져야 할 텐데 어떻게 업데이트되는가?
- 추측
- 웹 브라우저를 실행할 때마다 인증서 갱신 혹은 브라우저 업데이트 시 인증서 갱신
- 브라우저가 아닌 내부 시스템에 저장되어 있는 인증서 사용하는데 이를 정기적으로 업데이트 진행
- 맥 keychain
- 추측