HTTPS는 서로 다른 두 컴퓨터가 네트워크를 통해 안전하게 메세지를 주고받기 위해 만든 프로토콜이다. HTTPS는 TCP 대신 TLS(Transfer Layer Security) 프로토콜을 기반으로 하는 HTTP 라고 할 수 있다. TLS는 OSI 7 계층 중 4번째 계층(전송 계층)의 TCP 프로토콜을 기반으로 동작한다.
TLS가 등장하기 전 까지는 TLS 대신에 SSL 프로토콜을 사용했다. SSL은 많은 취약점으로 더 이상 사용하지 않지만, 여러 문서나 OpenSSL 등의 라이브러리는 SSL 이름을 계속 사용한다.
TLS 는 보안 세션 안에서 데이터를 암호화하며, 보안 세션을 만들기 위해 아래 3가지를 요구한다.
- 인증 메커니즘
- 키 교환 암호화 알고리즘
- 해싱 알고리즘
세션 : 운영체제가 일정한 기간 동안에 외부 유저가 자신의 리소스를 사용하는 것을 허락하는 것.
TLS Handshake 과정
1. 클라이언트가 서버에서 사이퍼 수트 전달하고 인증서 받기
- 클라이언트가 서버에게 사이퍼 수트를 전달한다.
- 서버는 클라이언트의 사이퍼 수트에서 제공 가능한 알고리즘 리스트가 있는지 확인한다.
- 제공가능한 알고리즘이 있다면 CA 인증서를 보내고 클라이언트는 서버를 신뢰할 수 있는지 확인한다.
사이퍼 수트 (cipher suite)
보안 통신에 필요한 암호화 알고리즘 모음이라고 보면 된다.
TLS 1.3 버전의 사이퍼 수트 내에 각 항목은 아래와 같은 형식으로 되어있다.
[프로토콜]_[AEAD]_[해싱 알고리즘]
TLS 1.3 버전의 사이퍼 수트는 아래 5가지로 구성되어 있다.
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
TLS 1.2 버전에서는 RSA 비대칭키 암호화 알고리즘 기반의 암호키 교환 방식을 지원했으나 비밀키가 탈취되면 미래에 송수신 될 메세지까지 제3자가 복호화 할 수 있다는 취약점 때문에 TLS 1.3 버전부터는 RSA를 사이퍼 수트에서 제외했다. RSA 말고도 해킹에 취약한 암호화 알고리즘들은 사이퍼 수트에서 모두 제외하고 위 5가지만 허용한다.
AEAD (Authenticated Encryption with Associated Data)
데이터의 기밀성, 무결성, 진정성을 보장하는 암호화 형식이다.
예를 들어
AES_128_GCM
은 128bit 짜리 키를 사용하는 고급 암호화 표준(AES, Advanced Encryption Standard)과 병렬 계산에 용이한 암호화 알고리즘 GCM(Galois/Counter Mode) 이 결합된 알고리즘을 뜻한다.SHA-256
SHA-2 계열 중 하나.
해싱 결과가 256bit 로 구성되어 있다. (2의 256 제곱만큼의 해시값을 만들어낸다.)
SHA-384
SHA-2 계열 중 하나.
해싱 결과가 384bit 로 구성되어 있다. (2의 384 제곱만큼의 해시값을 만들어낸다.)
2. 클라이언트가 서버를 신뢰할 수 있는지 확인
서버로부터 받은 인증서를 가지고 서버를 신뢰할 수 있는지 확인한다.
신뢰할 수 있는 기관에서 발급한 게 아니거나 기간이 만료되면 서버와의 연결을 허용하지 않는다.
CA 인증서
- 신뢰할 수 있는 인증 기관에서만 발급할 수 있다.
X.509
라는 표준을 따른다.
CA 인증서는 아래 항목들로 구성되어 있다.
- CA 주체 (이름, 도메인)
- 상위 발행기관
- 공개 키
- 디지털 서명
- 인증서 유효 기간
- 서버가 인증서를 보내면 브라우저는 위 그림과 같이 최상위 인증서를 찾을 때 까지 상위 인증서를 반복해서 가져온다.
모바일 기기를 포함한 대부분의 OS 는 최상위 기관 인증서 목록을 이미 가지고 있는데, 찾아낸 최상위 인증서와 기기가 가지고 있는 인증서 목록을 대조해서 신뢰하는 기관에서 발행한 인증서인지 확인한다.
- 최상위 기관에서 발행한 것이 확인되면, 최상위 인증서에 있는 공개키를 가지고 상위 인증서의 디지털 서명을 복호화한다. 이 때 상위 인증서의 디지털 서명은 최상위 발행기관이 만든 비밀키를 사용해 생성하므로, 위조된 서명은 복호화에 실패한다.
복호화에 성공하면 해시값이 나오는데, 이 해시값을 최상위 인증서의 해시값과 비교한다. (위 그림에서 파란색 1~2번에 해당.)
만약 복호화에 실패하거나 해시값이 일치하지 않으면 신뢰할 수 없는 인증서로 간주한다.
- 2번에서 해시값이 일치하면 상위 인증서에 있는 공개키를 가지고 서버 인증서의 디지털 서명을 복호화한다. 이 때 서버 인증서의 디지털 서명은 상위 발행기관이 만든 비밀키를 사용해 생성하므로, 위조된 서명은 복호화에 실패한다.
복호화해서 나온 해시값을 상위 인증서의 해시값과 비교하여 일치 여부를 확인한다. (위 그림에서 초록색 3~4번에 해당.)
- 이 과정이 모두 끝나면 브라우저는 서버를 신뢰할 수 있다고 간주한다.
TLS 1.2 버전 이상부터는 디지털 서명에 SHA-2 계열 알고리즘을 사용한다. SHA-1 알고리즘은 해싱 충돌 때문에 사용을 금지했으므로 SHA-1 알고리즘을 사용한 인증서로 확인되면 브라우저는 경고를 띄운다.
CA인증서는 브라우저 > 개발자도구 > security 탭에서 직접 확인 할 수 있다. 아래 이미지는 www.naver.com 으로부터 받은 CA인증서다.
DigiCert
라는 루트 인증기관에서 발급해준 것임을 알 수 있다. 루트 인증기관 목록은 www.checktls.com/showcas.html 에서 조회할 수 있다.
3. 클라이언트와 서버의 키 교환
3-1. 디피-헬먼 알고리즘 기반으로 키 교환하기
디피-헬만(Diffie-Hellman) 키 교환 알고리즘은 암호키를 교환할 때 사용하는 알고리즘이다.
y = g^x mod n
디피-헬만 알고리즘은 위 식에서
y
, g
, n
만으로는 x
를 구하기 어렵다는 원리에 기반한다.디피-헬만 키 교환 방식에서는 클라이언트와 서버가 각자의 비밀 키(private key)를 서로 알려주지 않으면서 동일한 암호키를 각자 만들 수 있는데, 아래 그림은 디피-헬만 알고리즘에 기반하는 키 교환 과정을 설명한다.
참고로 TLS 사이퍼수트에는 디피-헬만 알고리즘을 응용한 ECDHE(Elliptic-curve Diffie–Hellman Exchange) 방식도 포함되어 있다. ECDHE 경우 아래 그림에서 설명하는 DH parameter 외에 더 많은 파라미터를 요구한다.
위 과정에서 네트워크 상의 제3자가 패킷을 탈취해서 퍼블릭하게 공개된 파라미터들을(
g=3
, n=17
, 12
, 6
) 알아낸다고 하더라도 서버의 비밀키(= 15
), 클라이언트의 비밀키(= 13
)는 뭔지 알 수 없다. 따라서 서버와 클라이언트가 각자 가지고 있는, 동일하지만 전혀 공유되지 않은 pre-master secret, session key 를 제3자는 만들 수 없으므로 클라이언트와 서버 간에 암호화되어 송수신되는 세그먼트를 복호화 할 수 없다.
위 과정에서 생성된 pre-master secret 은 PSK(pre-shared key) 라고도 한다.
3-2. TLS 1.3 버전에서의 키 교환 과정
위 핸드쉐이크 과정의 단점은 RTT(Round Trip Time) 가 여러 번 발생한다는 것이다.
TLS 1.3 버전에서는 이 단점을 보완하기 위해 1-RTT 만으로 키 교환을 해결한다.
TLS 1.3 에서 제공하는 사이퍼수트에는 암호키 교환 방식이 DHE, ECDHE 두 가지만 있기 때문에 서버가 항상 디피-헬만 알고리즘을 선택한다는 걸 가정하므로 아래와 같은 1-RTT 핸드쉐이크가 가능하다.
참고 자료