HTTPS와 SSL인증서 & 대칭키, 공개키(비대칭키)

dong5854·2022년 2월 18일
9

HTTPS와 HTTP

HTTP

HTTP는 Hyper-Text Transfer Protocol의 약자로, Hypertext인 HTML을 주고받기 위한 규약(protocol)이다.

HTTPS

HTTPS에서 마지막의 S는 over Secure socket Layer의 약자로 HTTP에서 보안이 강화된 버전이다.

HTTPS의 중요한 역할은 크게 3가지이다.

첫째로 암호화를 통해 클라이언트가 정보를 서버와 안전하게 주고받도록 해준다. 즉, 제 3자가 클라이언트가 서버에 보내는 정보들을  못보게 하는 역할이다.

두번째로는 접속한 사이트가 신뢰할만한 사이트인지 알려주는 역할이다.

세번째로는 통신 내용의 악의적인 변경을 방지할 수 있다.

HTTPS와 SSL

HTTPS는 'Hyper-Text Transfer Protocol over Secure socket Layer'라는 풀네임으로 알 수 있듯이 SSL 프로토콜 위에서 돌아가는 HTTP 프로토콜이라고 할 수 있다.

SSL과 TLS

같은 말이다. 네스케이프에 의해서 SSL이 발명되었고, 이것이 점차 폭넓게 사용되다가 표준화 기구인 IETF의 관리로 변경되면서 TLS라는 이름으로 바뀌었다. TLS 1.0은 SSL 3.0의 업그레이드 버전으로 큰 차이는 없으나 취약점들이 해결되었다.

대칭키와 공개키(비대칭키)

HTTPS의 보안 기능에 대해 이해하려면 먼저 대칭키와 공개키(비대칭키)에 대한 이해가 필요하다.

대칭키

키란 암호화를 진핼할 때 사용되는 비밀번호와 같은 역할을 한다. 이 키에 따라 암호화된 결과가 달라지기 때문에 키를 모르면 복호화 또한 할 수 없다. 대칭키는 암호화에 사용되는 키와 복호화에 사용되는 키가 동일일 암호화 기법이다.
대칭키 암호화

예를 들어 암호화 전의 메세지를 키A를 통해 암호화를 진행했다면,
대칭키 복호화
암호화된 내용은 암호화를 사용할 때 사용된 키A를 통해 복호화 되는것도 가능한 기법이 대칭키이다.

대칭키 방식에는 명확한 단점이 있는데 이 암호화와 복호화를 필요한 키의 공유가 어렵다는 것이다. 결국 암호화된 메세지를 상대가 복호화 시킬 수 있게 하기위해서는 적어도 한번은 이 대칭키의 공유가 이루어져야 하는데, 이 과정에서 대칭키가 유출되면 키를 획득한 사람은 누구나 복호화를 할 수 있기 때문에 암호가 무용지물이 되기 때문이다. 이러한 단점을 보완한 암호화 방식이 공개키(비대칭키) 방식이다.

공개키(비대칭키)

공개키 방식은 두개의 키를 갖게 되는데 A키를 사용해 암호화를 하면 B키로 복호화를 할수 있고, B키로 암호화를 하면 A키로 복호화를 할 수 있는 방식이다.
공개키 암호화 복호화 1
즉, 키A를 통해 암호화한 내용은 키A를 이용해 복호화 하는 것은 불가능하고 키A와 쌍을 이루는 키B를 사용해야만 복호화가 가능하다.
공개키 암호화 복호화 2

이와 반대로 키B를 통해 암호화된 내용은 키B로 복호화하는 것은 불가능하고 키A를 통해서만 복호화가 가능하다.

이 방식에 착안해서 이 두개의 키 중 하나를 비공개키(private key, 개인키, 비밀키라고도 부른다)로 하여 자신만이 가지고 있고, 나머지를 공개키로 지정하여 대중에게 공개한다. 클라이언트는 이 공개키를 사용하여 비밀번호화 같은 정보를 암호화 하여 서버에 보내면 서버는 자신이 보관하고 있던 비공개키를 사용하여, 암호화된 내용을 복호화 할 수 있다.
공개키, 비밀키
이 과정에서 공개키가 유출이 된다고 해도 공개키를 이용해서는 오직 암호화만 가능하고 복호화는 오직 서버에서 보관중인 비밀키(비공개키)로만 가능하기 때문에 정보가 안전하다.

이 방식은 다른 방식으로도 응용이 가능한데, 만약 공개키가 검증이 되었다면 이를 이용하여 암호화된 정보의 출처를 검증이 가능하다.
공개키를 사용하여 출처 검증

위의 그림에서 만약 A사의 공개키 keyA가 A사의 공개키가 맞다는 것이 검증이 된 경우에 A사가 정보를 A사의 비밀키를 사용하여 암호화를 한 정보는 keyA를 사용하여 복호화가 가능하여야 한다. 만약 keyA를 통해 복호화가 불가능하다면 해당 정보의 출처는 A사가 아니라는 것을 알 수 있다. 여기서 공개키 keyA가 A사의 공개키가 맞다는 것은 누가 검증해줄 수 있을까? 이러한 역할을 해주는 공인된 민간기업들을 CA(Certificate Authority)라고 한다. CA의 대한 설명을 아래에서 추가로 진행하겠다.

SSL 인증서

SSL 인증서의 기능은 크게 두가지이다.

1. 클라이언트가 접속한 서버가 신뢰 할 수 있는 서버임을 보장한다.

2. SSL 통신에 사용할 공개키를 클라이언트에게 제공한다.

CA(Certificate Authority)

인증서의 역할 중에서는 클라이언트가 접속한 서버가 클라이언트가 의도한 서버가 맞는지를 보장해주는 역할을 하는데 이런 역할을 하는 민간기업들을 CA(Certificatie Authority) 혹은 Root Certificate라고 부른다. CA는 엄격한 인증과정을 거친 신뢰성이 공인된 기업들만이 할 수 있다. SSL을 통해서 암호화된 통신을 제공하려는 서버스는 CA를 통해서 인증서를 구입해야 한다. CA는 서비스의 신뢰성을 다양한 방법으로 평가한다.

브라우저 안의 CA 리스트

크롬, 파이어폭스, 엣지, 사파리 등의 브라우저에는 내부적으로 CA의 목록이 내장되어 있다. 이렇게 브자우저에 내장되어있는 CA의 리스트에 포함되어야만 공인된 CA가 될 수 있다. 브라우저는 CA의 리스트 뿐만이 아니라 CA의 공개키 또한 알고 있다.

사설 인증기관

개발이나 사적인 목적을 위해 SSL의 암호화 기능을 사용하기 위해서 자신이 직접 CA의 역할을 수행할 수도 있지만 이는 당연히 브라우저의 CA리스트에 포함된 공인된 인증서가 아니기 때문에 브라우저가 경고를 출력한다.

SSL 인증서의 내용

SSL 인증서에는 크게 2가지로 구분되는 내용이 포함되어 있다.

1. 서비스의 정보(인증서를 발급한 CA, 서비스의 도메인 등등)

2. 서버 측 공개키(공개키의 내용, 공개키의 암호화 방법)

위와 같은 내용들은 CA에 의해서 암호화가 되는데 CA는 자신의 CA 비공개키를 이용해서 서버가 제출한 인증서를 암호화 하는 것이다.

즉, 서비스의 제공을 원하는 사람이 CA의 인증서의 발급을 요청하면 위의 내용들을 CA가 자신들의 비공개키를 통해 암호화를 하여 발급해준다.

SSL 인증서가 서비스를 보증하는 방법

SSL 인증서의 두가지 기능중에 언급했던 클라이언트가 접속한 서버가 신뢰 할 수 있는 서버임을 보장하는 것이 있었다. 어떤 메커니즘으로 인증서가 서버의 신뢰성을 보장하는지 알아보자.

인증서가 서버의 신뢰성을 보장받는 과정은 아래와 같다.

1. 웹 브라우저가 서버에 접속할 때 서버는 브라우저에 인증서를 제공한다.

2. 웹 브라우저는 이 인증서를 발급한 CA가 자신이 내장한 CA의 리스트에 있는지를 확인한다.

3. 확인 결과 서버로부터 받은 인증서가 브라우저에 내장된 CA리스트에 포함되어 있는 CA로부터 발급받은 것이라면 해당 CA의 공개키를 이용해 인증서를 복호화한다. => 해당 절차를 통해 이 인증서가 CA의 비공개키에 의해서 암호화 된 것을 보장한다.

4. CA에 의해서 발급된 인증서라는 것은 접속한 사이트가 CA에 의해 검토된 신뢰 할 수 있는 사이트라는 것을 의미한다.

위와 같은 과정을 통해 인증서가 서버의 신뢰성을 보장한다.

SSL의 동작방법

위에서 SSL 인증서에는 서버 측 공개키가 포함되어 있다고 했는데, 이는 암호화된 데이터를 전송하기 위한 과정에서 필요하다. 이 서버에서 클라이언트에게 제공하는 공개키와 서버가 가지고 있는 비밀키만을 사용하여 암호화를 진행하여 통신한다면 이상적이겠지만 실제로 이러한 방식에는 무리가 있는데 이는 공개키 방식을 사용하면 암호화, 복화화 과정에서 컴퓨팅 파워가 많이 사용되어 성능적인 문제가 발생할 수 있기 때문이다.

이러한 문제 때문에 SSL은 공개키와 대칭키를 혼합해서 사용하여 성능적인 이점과 보안적 관점에서의 이점을 동시에 취한다. 어떠한 방식으로 공개키와 대칭키가 혼합되는지 알아보기에 앞서 실제 데이터는 대칭키를 사용하여 암호화되어 암호화, 복호화 과정에서 컴퓨팅 파워를 덜 소모하고, 이때 사용되는 대칭키의 공유를 위한 암호화 기법으로 공개키를 사용한다는 것을 유념해두자.

컴퓨터와 컴퓨터가 네트워크를 이용해서 통신을 할 때는 내부적으로 3가지 단계가 있다.

악수(handshake) -> 전송 -> 세션 종료

1. 악수 (handshake)

SSL 방식을 이용한 통신 역시 브라우저와 서버가 핸드쉐이크를 하는데 이 단계에서 클라이언트와 서버가 통신하는 과정을 순서대로 보면 아래와 같다.

1. 클라이언트가 서버에 접속한다. 이 단계를 Client Hello라고 한다. 이 단계에서는 아래와 같은 정보를 주고받는다.

- 클라이언트 측에서 생성한 랜덤 데이터

- 클라이언트가 지원하는 암호화 방식들: 클라이언트와 서버가 지원하는 암호화 방식이 서로 다를 수 있기 때문에 상호간에 사용할 암호화 방식을 결정하기 위해 클라이언트 측에서 자신이 사용할 수 있는 암호화 방식을 전송한다.

- 세션 아이디: 이미 SSL 핸드쉐이킹을 했다면 비용과 시간을 절약하기 위해서 기존의 세션을 재활용하게 되는데 이 때 사용할 연결에 대한 식별자를 서버 측으로 전송한다.

2. 서버는 Client Hello에 대한 응담으로 Server Hello를 하게 된다. 이 단계에서 주고 받는 정보는 아래와 같다.

- 서버 측에서 생성한 랜덤 데이터

- 서버가 선택한 클라이언트의 암호화 방식: 클라이언트로부터 전달받은 암호화 방식 중에서 서버 쪽에서도 사용 가능한 암호화 방식 중에 가장 안전한 암호화 기법을 선택하여 클라이언트에게 전달하여 해당 암호화 방식을 이용해 정보를 교환하게 된다.

- 인증서

3. 클라이언트는 위에서 설명한 'SSL 인증서가 서비스를 보증하는 방법'에 의하여 인증서를 통해 서버의 신뢰성을 보장받는다.

4. 클라이언트는 2번에서 받은 서버 측에서 생성한 랜덤 데이터클라이언트 측에서 생성한 랜덤 데이터를 조합하여 pre master secret이라는 키를 생성한다. 이 키는 뒤에서 나올 세션 단계에서 데이터를 주고 받을 때 암호화 하기 위해서 사용될 것이다. 이 때 사용할 암호화 기법은 대칭키이기 때문에 pre master secret 값은 제 3자에게 절대로 노출되면 안된다.

이 pre master secret값이 제 3자에게 노출되지 않고 서버에게 전달되기 위해 사용되는 방식이 공개키 방식이다. SSL 인증서로부터 전달 받은 서버의 공개키로 pre master secret 값을 암호화해서 서버로 전송하면 pre master secret값은 제 3자에게 노출의 위험없이 서버의 비밀키로 안전하게 복호화가 가능하다.

5. 서버는 클라이언트가 전송한 pre master secret 값을 자신의 비공개키로 복호화 함으로서 서버와 클라이언트는 모두 pre master secret값을 공유하게 되었다. 그리고 서버와 클라이언트는 모두 일련의 과정을 거쳐 pre master secret값을 master secret 값으로 만든다. master secert은 session key를 생성하는데 이 session key 값을 이용해 서버와 클라이언트는 데이터를 대칭키 방식으로 암호화 한 후에 주고받는다. 이렇게해서 세션키를 클라이언트와 서버가 모두 공유한다.

6. 클라이언트와 서버는 핸드쉐이크 단계의 종료를 서로에게 알린다.

2. 세션

세션은 실제로 서버와 클라이언트가 데이터를 주고 받는 단계이다. 이 단계에서 핵심은 정보를 상대방에게 전송하기 전에 session key 값을 이용해서 대칭키 방식으로 암호화 한다는 점이다. 상대방 또한 세션키 값을 알고 있기 때문에 암호화된 정보는 복호화 될 수 있다.

3. 세션 종료

데이터의 전송이 끝나면 SSL 통신이 끝났음을 서로에게 알려준다. 이 때 통신에서 사용한 대칭키인 세션키를 폐기한다.

본 게시물은 생활코딩 이고잉님의 HTTPS와 SSL 인증서
https://opentutorials.org/course/228/4894
HTTPS Wikipedia
https://en.wikipedia.org/wiki/HTTPS
얄팍한 코딩사전님의 HTTPS가 뭐고 왜 쓰나요?(Feat. 대칭키 vs 비대칭키)
https://www.youtube.com/watch?v=H6lpFRpyl14
를 참고하여 작성되었습니다.

profile
https://github.com/dong5854?tab=repositories

0개의 댓글