ㅂㄱ
HTTPS 본문
HTTP
•HTTP는 Hypertext Transfer Protocol의 약자다. 즉 Hypertext 인 HTML을 전송하기 위한 통신규약을 의미한다.
•즉 문서와 문서가 링크로 연결된 문서, 문서체계인 HTML을 전송하기 위한 통신 규약입니다.
HTTPS
•HTTPS에서 마지막의 S는 Over Secure Socket Layer의 약자로 Secure라는 말을 통해서 알 수 있듯이 보안이 강화된 HTTP라는 것을 짐작할 수 있습니다.
HTTP -> HTTPS로 개선
•악의적인 감청이나 위 변조에 대응하기 위해서 HTTP를 개선해야 하는데 개선 내용은 아래와 같습니다.
•기밀성 : 통신 내용이 공격자에게 노출되는 것을 막아야 합니다.
•인증 : 클라이언트가 접속하려는 서버가 신뢰 할 수 있는 서버인지를 판단할 수 있어야 합니다.
•무결성 : 통신 내용의 악의적인 변경을 방지할 수 있어야 합니다.
인증서를 사용하는 이유
오늘 날 많은 사람들이 네트워크를 통해 패킷을 주고 받습니다. 그러나 전통적으로 네트워크는 여러 공격자로부터의 위협이 도사리는 공간으로 간주되어 왔습니다. 우리가 특정 서버에 요청을 주고 받을 때 수 많은 라우터와 스위치를 거치게 되는데, 그 중간에서 누군가가 우리의 패킷을 훔쳐 (Sniffing) 볼 수 있기 때문이다. 패킷을 훔쳐 본다는 것은 결국 우리가 입력한 데이터, 예컨대 비밀번호와 같이 민감한 정보를 제 3자가 열람할 수 있다는 뜻이기 때문에 이를 미연에 방지하기 위한 많은 방법들이 연구되어 왔습니다.
만약 네트워크 데이터가 암호화된다면, 중간에 공격자가 패킷을 열람하더라도 데이터가 유출되는 것을 막을 수 있습니다. 오늘날 가장 널리 쓰이고 있는 암호화 방식이 SSL/TLS1 라는 것인데, 이 방식은 '인증서' 라고 하는 일종의 서명을 사용합니다. 자세한 동작 원리는 뒤에서 다시 설명하겠지만, 인증서라는 것은 결국 '당신이 신뢰할 수 있는 사람이냐' 라는 것을 확인하기 위한 용도이며 이것이 패킷 데이터를 암호화하기 위한 첫 단계라고 생각하면 됩니다.
인증서가 신뢰할 수 있다는 검증 작업을 거치고 나서야 비로소 데이터 암호화 작업이 수행된다. 그 과정이 SSL 보안 통신이라고 불리는 것이며, 이론상 이를 해독하는 것이 거의 불가능하기 때문에 오늘날 다양한 보안 연결에서 사용되고 있습니다.
우리가 흔히 사용하고 있는 (그렇지만 잘 인지하지 못하고 있는) 보안 연결은 다름아닌 웹 브라우저 <-> 웹 사이트 간 연결입니다.
인증서(CA)
웹브라우저의 주소 옆에 자물쇠는 인증서 (CA) 를 통해 브라우저-웹 서버 간 보안 연결이 수립되었다는 것을 의미합니다. 그러나 인증서를 사용하지 않은 웹 서버의 경우 위 그림의 오른쪽처럼 '주의 요함' 이라는 문구가 출력되는데, 이는 데이터가 암호화되지 않은 채로 전송되고 있으며 네트워크에 존재할 수 있는 공격자가 스니핑, 스푸핑 등을 통해 패킷을 훔쳐볼 경우 데이터가 전부 유출될 수 있음을 뜻한다.
보안 연결의 순서
빠른 이해를 위해서 간단하게만 설명하자면, 서버와 클라이언트 간 보안 연결은 크게 두 가지 단계로 나누어진다.
첫 번째 단계는 클라이언트의 CA를 통해 서버 인증서가 신뢰 가능한지를 확인하는 단계이다. 간단하게 말해서, '당신 (서버) 가 신뢰할 수 있는 사람이냐' 라는 것을 '인증서' 를 통해 검증한다. 인증서 검증을 통해 서버가 신뢰할 수 있다고 판단되면, 클라이언트는 두 번째 단계인 보안 연결 수립 단계를 진행한다. 서버-클라이언트 간에 생성된 랜덤 값을 통해 대칭 키를 생성하고, 이를 통해 네트워크 데이터를 암호화해 전송한다.
결국은 인증서를 통한 신뢰 검증 (첫 번째 단계) 이 완료되어야만 보안 연결 수립 (두 번째 단계) 을 할 수 있으므로, 인증서가 어떠한 원리로 동작하는지를 이해하는 것이 중요하다.
인증서의 구조
(널리 알려진) 신뢰 가능한 기관
이 세상에는 무조건 신뢰할 수 있는 기관이 몇 군데 존재한다. 그 기관들은 보통 최상위 인증 기관이라고 불리며, Root CA라는 인증서를 발급하는 기관입니다.
이 기관들은 본인들만의 고유한 비밀 키를 가지고 있고, 이에 대응하는 공개 키를 전 세계에 배포합니다. 그리고 세상 사람들은 암묵적으로 이 기관들은 신용할 수 있음을 서로 약속하고, 배포된 Geotrust의 공개 키로 복호화가 가능한 데이터는 Geotrust의 비밀키로 암호화되었기 때문에 신용할 수 있는 데이터라고 간주합니다. 물론 Geotrust의 비밀 키는 철저한 보안 속에서 절대로 유출되지 않아야만 한다는 전제 조건이 필요하긴 하지만, 이러한 기관은 보안을 전문으로 하는 회사이기 때문에 보통은 안전하다고 생각하면 됩니다.
일반적으로 이렇게 신뢰 가능하다고 여겨지는 기관의 공개 키는 여러분의 컴퓨터에 이미 설치되어 있는 경우가 많다. Mac OS 라면 키체인에 있을 것이고, 여러분의 웹브라우저인 파이어폭스, 크롬 등에도 Geotrust의 공개 키는 이미 내장되어 있다.
일반적인 인증서의 작동 방식
•이 세상에는 '인증서' 라고 부르는, 내가 신뢰할 수 있는 사람인지를 증명하기 위한 파일이 존재합니다. 그렇다면 인증서는 어떻게 내가 신뢰할 수 있음을 증명하는 것일까요?
인증서의 내용물
상대방이 신뢰할 수 있는지 검증하기 위해 존재하는 '인증서' 라는 포맷의 파일에 대해서 먼저 알아보자. 인증서 파일 안에는 다양한 내용이 저장되어 있으며, 대표적인 내용물은 아래와 같다.
(1) 인증서의 소유자 이름,
(2) 인증서 소유자의 공개 키 (당연히 비밀 키는 소유자가 가지고 있다),
(3) 인증서의 유효 기간,
(4) 고유한 UID
(5) 인증서의 기타 모든 값들을 해시화한 값
그리고 가장 중요한 것은, (5) 의 값 : 인증서의 내용을 종합해 해시화한 값을 암호화한 값 (지문)
인증서의 구조
Geotrust <-> Google CA 예시 (2계층)
인증서는 계층 구조로 되어 있습니다. 보통 3계층 구조로 되어 있고, 가장 최상위에 위치한 인증서는 일반적으로 Root 인증서라고 불립니다. 이러한 Root 인증서는 세상 사람들이 모두 신뢰하기로 약속한 기관, 예를 들어 위에서 언급한 Geotrust 등의 기관에서 발행한 인증서가 됩니다.
이러한 인증서는 일반적으로 웹 브라우저 등에 미리 내장되어 있으며, 해당 인증서에 대응하는 공개 키 또한 인증서 내부에 포함되어 있습니다.
위 그림을 기준으로 설명하면, 가장 최상위 Root 인증서의 주인은 Geotrust 회사입니다.
자신의 인증서를 만들고 싶은 Google CA 회사는 Geotrust에게 이렇게 요청합니다.
'당신네들은 신뢰 가능한 회사로 알려져 있습니다.
나는 Google CA 회사의 인증서를 만드려고 해요. 내 인증서의 내용물을 드릴테니, 인증서의 내용물을 종합해 해시화한 값을 당신네 (Geotrust) 회사의 비밀 키로 암호화 해주세요?
인증서의 내용물을 종합해 해시화한 값을 Geotrust의 비밀 키로 암호화해달라고 하는 이유는 간단하지만 매우 중요합니다. 세상 사람들은 Geotrust 회사의 공개 키를 전부 가지고 있고, 이 공개 키로 복호화되는 데이터는 신뢰할 수 있는 데이터임을 알고 있습니다.
만약 세상 사람들이 Google CA 인증서를 누군가로부터 전달받은 뒤, Google CA 인증서 내부의 암호화된 해시 값을 Geotrust의 공개 키를 이용해 복호화에 성공했다고 가정해봅시다. 그렇다면 Google CA의 인증서의 내용물에 대한 해시 값을, Geotrust가 Geotrust의 비밀 키로 암호화 해준것일테니, Google CA 또한 신뢰할 수 있다고 간주하는 것입니다.
이러한 원리를 Chain of Trust라고 부릅니다.
상위 계층의 인증서 (Geotrust) 가 신뢰할 수 있는 기관이라면, 해당 인증서 (Geotrust) 의 비밀 키로 암호화된 하위 인증서 (Google CA) 또한 신뢰 가능하다고 간주합니다.
그렇다면 굳이 인증서의 내용물로 해시 값을 만든 뒤, 이 값을 Geotrust의 비밀 키로 암호화한 이유는 무엇일까요?
사람들이 모두 갖고 있는 Geotrust의 공개 키를 이용해, Geotrust의 하위 인증서인 Google CA 인증서의 암호화된 해시값을 복호화했고, Google CA의 인증서를 생성할 당시에 사용한 해시 값을 얻었다고 가정해보자. 여기까지만 보면 Google CA의 인증서는 어쨌든 Geotrust에 의해 신뢰 가능하다고 생각될 수는 있다. 그런데, (1) 복호화된 해시 값과 (2) 인증서에 들어 있는 내용물을 다시 해시값으로 만들어 비교를 해보니 동일한 값이 아니라면 어떨까?
이는 곧 Google CA 인증서의 내용물이 누군가에 의해 변조되었음을 의미한다!
따라서, 상위 인증서 기관의 공개 키로 하위 기관의 인증서 해시 값을 복호화 한다는 것은 두 가지 효과를 얻을 수 있음을 알 수 있다.
먼저, (1) Chain of Trust의 원리에 의해 하위 인증서가 신뢰할 수 있는지를 알 수 있으며, (2) 하위 인증서의 내용물이 변조되었는지를 알 수 있게 됩니다.
Geotrust <-> Google CA <-> 개인 인증서 예시 (3계층)
위 예시는 Geotrust와 Google 간의 예시를 보여주었지만, 실제로 웹 브라우저에는 Geotrust와 Google CA의 인증서가 신뢰할 수 있도록 미리 등록되어 있습니다. 최상위 인증서 기관과 중간 인증서 기관까지는 사실상 신뢰할 수 있도록 설정되어 있기 때문에 우리가 Geotrust와 Google CA에 대해 의심할 필요는 없다고 보면 됩니다.
즉 중간 인증서 기관은 모두 신뢰할 수 있으며 Root CA 인증서와 구분짓기 위해 ICA (Intermediate CA) 라고 부른다. 이러한 ICA 또한 일반적으로 신용도가 높은 회사 (예를 들면 Google) 로 구성되어 있기 때문에 신뢰할 수 있는 인증서 목록에 기본적으로 ICA가 등록되어 있습니다. 그렇다면 이번에는 Google과 같은 큰 회사의 ICA가 상위 인증서가 되는 경우를 살펴보도록 하자. 나와 같은 개인이 인증서를 발급받으려면 일반적으로 Root 인증서가 아닌 ICA에 인증서의 사인 (인증서 내용물 해시값의 암호화) 를 요청하게 된다.
필자와 같은 개인이 Google CA에 인증서 생성을 요청 (해시값의 암호화 요청) 을 보내면 Google CA는 Google CA의 비밀키를 이용해 해시값을 암호화함으로써 인증서에 서명하게 된다. Geotrust와 Google CA 예시에서 보았던 것처럼, alicek106 인증서에 저장된 암호화된 해시 값은 Google CA로만 복호화할 수 있다.
우리는 Google CA가 신뢰할 수 있는 기관임을 Geotrust의 공개 키 (Geotrust의 인증서) 를 통해 검증했다. 그런데 Google CA의 공개 키를 통해 alicek106 인증서에 내장된 암호화된 해시 값의 복호화에 성공했다면, alicek106의 인증서 또한 Google CA에 의해 신뢰할 수 있음을 인증하게 된다.
최종적으로 alicek106은 Geotrust에 의해 신뢰될 수 있는 인증서를 갖게 된다.
여기서 한 가지 알아둘 점은, 최상위 인증서인 Root 인증서는 스스로를 사인해줄 상위 기관이 없기 때문에 스스로 보증 (Self-signed) 하게 된다. Geotrust와 같은 Root CA가 발행하는 인증서가 이에 해당하며, 이러한 최상위 인증 기관은 모두가 믿기로 약속했기 때문에 크게 문제가 되지 않는다고 한다.
보안 연결 수립 과정
개인이 ICA로부터 인증서를 발급받았고, 이를 웹 사이트에 등록했다. 그리고 사용자 (클라이언트) 가 해당 웹 서버에 접속해 데이터를 주고받으려고 할 때, 보안 연결 수립을 위해 어떠한 과정이 발생하는지 알아보자.
이 글의 [2. 보안 연결의 순서] 항목에 있는 그림을 좀 더 구체화하면 위와 같이 표현할 수 있다. 클라이언트가 웹 사이트에 접근하면 서버 측에서는 자신의 인증서 및 ICA 인증서를 클라이언트에게 전송합니다.
물론, 클라이언트의 웹 브라우저에는 해당 인증서가 신뢰할 수 있는지를 확인하기 위해 '신뢰할 수 있는 인증서' (공개 키) 가 미리 등록되어 있습니다.
위에서 말했다시피, '신뢰할 수 있는 인증서' 목록에는 Geotrust와 같은 Root CA의 인증서, Google CA같은 ICA의 인증서가 포함되어 있다.
위 그림과 같이 클라이언트에게 ICA의 인증서와 alicek106의 인증서가 함께 전달되고, 웹 브라우저에 등록된 인증서 (공개 키) 에 의해 alicek106 인증서는 신뢰할 수 있는지를 확인하는 작업을 수행한다.7 alicek106 인증서가 상위 인증서 (Google CA)에 의해 신뢰될 수 있음을 확인하고 나면 클라이언트는 alicek106 인증서에 내장되어 있는 alicek106의 공개 키를 꺼내 사용하게 된다.
결론부터 말하자면, 비대칭키의 암호화/복호화는 대칭키에 비해 자원을 많이 사용하기 때문에, 클라이언트와 서버가 최초로 비밀 값을 주고 받을 때 (Client Key Exchange 단계) 에만 비대칭키를 통해 암호화한다. 즉 서버와 클라이언트 간에 처음 연결을 수립할 때에만 비대칭키를 사용하고, 보안 연결 수립 뒤에는 대칭 키로 패킷을 암호화해 전송한다. 그 과정을 나타내면 아래 그림과 같다.
클라이언트와 서버는 연결을 수립하기 이전에, Handshake 과정에서 각각 Nonce (Seed 값) 를 주고 받는다. 즉 클라이언트는 클라이언트의 Nonce 값을 생성해서 서버로 전송하고, 서버는 서버의 Nonce 값을 생성해 클라이언트로 전송한다. 여기까지는 아직 데이터가 암호화되어서 전송되지 않는다! 그리고 나서야 클라이언트는 PMS (Pre-master secret) 라고 불리는 일종의 난수 값을 생성하고, 인증서로부터 획득한 alicek106의 공개 키를 이용해 PMS 값을 암호화한 뒤 이를 서버로 전송한다.
서버와 클라이언트는 {클라이언트/서버 Nonce 값, PMS 값} 을 통해 비로소 대칭 키를 생성하게 되고, 서버와 클라이언트는 이 대칭 키를 이용해 데이터를 암호화하게 된다. 길고 긴 암호화 과정이 끝났기에, 여기서부터 본격적으로 암호화된 보안 통신이 시작된다!