SSL이 없다면?
네트워크 상에서 SSL을 적용하지 않고 데이터를 전송하면 암호화되지 않은 데이터가 전송될 것이다. 이렇게 되면 스누핑, 스니핑 위협에 노출될 수 있다. 이를 방지하기 위해 상호간 정당한 사용자인지 인증서를 통해 검증하고 서로 약속한 암호화 알고리즘을 통해 키를 교환 후 암호화 통신을 이어간다.
SSL/TLS에는 양방향 인증/단방향 인증이 있다.
(4~5번은 handshake 하는 과정이다. https 전송전에 요청을 통해서 받게 된다.)
SSL/TLS 세션은 다음 hanshake 과정을 거친 후에 구축된다.
위 과정이 끝나면 SSL 세션이 구축되며 실제 암호화 통신을 시작할 수 있다.
HTTPS 통신과정에서도 송신자와 수신자가 암호화 통신을 하기 위한 방법과 수단에 대해 공유한다.
즉, 데이터를 암호화할 대칭키(비밀키)를 타인에게 노출시키지 않고 클라이언트가 서버에게 전송하기 위해 협상을 벌이는 것이다. SSL Handshake(TLS Handshake)가 그 방법으로, 송신자와 수신자가 암호화된 데이터를 교환하기 위한 일련의 협상과정을 의미한다 협상과정에는 SSL 인증서 전달, 대칭키(비밀키) 전달, 암호화 알고리즘 결정, SSL/TLS 프로토콜 결정 등이 포함된다.
- 암호화 알고리즘(Cipher Suite) 결정
- 데이터를 암호화할 대칭키(비밀키) 전달
위 두가지를 기억하면서 순서대로 보자.
클라이언트가 서버에 연결을 시도하며 전송하는 패킷이다. 자신이 사용 가능한 Cipher Suite 목록, Session ID, SSL Protocol Version, Random byte 등을 전달한다. Cipher Suite는 SSL Protocol version, 인증서 검증, 데이터 암호화 프로토콜, Hash 방식 등의 정보를 담고 있는 존재로 선택된 Cipher Suite의 알고리즘에 따라 데이터를 암호화하게 된다. 아래 사진을 보면 클라이언트가 사용 가능한 Cipher Suite를 서버에 제공하는 것을 알 수 있다.
클라이언트가 보내온 ClientHello 패킷을 받아 Cipher Suite 중 하나를 선택한 다음 클라이언트에게 이를 알린다. 또한 자신의 SSL Protocol version 등도 같이 보낸다. 아래 사진을 보면 ClientHello에서 17개였던 Cipher Suite와 달리 아래에선 서버가 선택한 한 줄(Cipher Suite : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)만이 존재하는 것을 알 수 있다. 클라이언트가 보낸 리스트에 있는 Cipher Suite 중에 한 개를 선택한 것이다.
서버가 자신의 SSL 인증서를 클라이언트에게 전달한다. 인증서 내부에는 서버가 발행한 공개키(+개인키는 서버가 소유)가 들어있다. 클라이언트는 서버가 보낸 CA(Certificate Authority, 인증기관)의 개인키로 암호화된 이 SSL 인증서를 이미 모두에게 공개된 CA(Certificate Authority, 인증기관)의 공개키를 사용하여 복호화한다. 복호화에 성공하면 이 인증서는 CA(Certificate Authority, 인증기관)가 서명한 것이 맞는 것이니 진짜임이 증명되는 것이다. 즉, 인증서를 검증하는 것이다.
또한 클라이언트는 데이터 암호화에 사용할 대칭키(비밀키)를 생성한 후 SSL 인증서 내부에 들어있던(서버가 발행한) 공개키를 이용해 암호화하여 서버에게 전송할 것이다. 아래를 보면 SSL 인증서가 무슨 알고리즘(RSA)으로 암호화되었고, 무슨 Hash 알고리즘(SHA256)으로 서명되었는지 확인 가능하다.
‘Server Key Exchange’는 서버의 공개키가 SSL 인증서 내부에 없는 경우, 서버가 직접 전달함을 의미한다. 공개키가 SSL 인증서 내부에 있을 경우 Server Key Exchange는 생략된다. 인증서 내부에 공개키가 있다면 클라이언트가 CA(Certificate Authority, 인증기관)의 공개키를 통해 인증서를 복호화한 후 서버의 공개키를 확보할 수 있다. 그리고 서버가 행동을 마쳤음을 전달한다.
위의 경우, 키 교환 알고리즘이 Diffie-Hellman(DH, DHE 등) 알고리즘이기에 키 교환 재료를 서로 교환하므로 ‘Server Key Exchange를 발생시키는 것이다. 아래 ‘Client Key Exchange’에서 자세히 설명한다.
대칭키(비밀키, 데이터를 실제로 암호화하는 키)를 클라이언트가 생성하여 SSL 인증서 내부에서 추출한 서버의 공개키를 이용해 암호화한 후 서버에게 전달한다. 여기서 전달된 ‘대칭키’가 바로 SSL Handshake의 목적이자 가장 중요한 수단인 데이터를 실제로 암호화할 대칭키(비밀키)이다. 이제 키를 통해 클라이언트와 서버가 교환하고자 하는 데이터를 암호화한다.
위의 캡쳐를 보고 의아한 생각이 들 것이다. 클라이언트가 데이터를 암호화할 대칭키(비밀키)를 보낸다고 했는데 ‘EC Diffie-Hellman Client Params’, 즉 키를 생성할 재료를 보낸다는 것으로 보인다. 키교환 알고리즘을 RSA가 아닌 Diffie-Hellman(DH, DHE 등) 알고리즘과 타원곡선 암호인 ECDHE(Elliptic Curve DHE)을 사용하게 된다면 클라이언트가 데이터를 암호화할 대칭키(비밀키)를 보내는 것이 아니라 대칭키(비밀키)를 생성할 재료를 클라이언트와 서버가 교환하게 된다. 그리고 서로 교환한 각자의 재료를 합쳐 동일한 대칭키를 만들 수 있다. Diffie-Hellman(DH, DHE 등)과 타원곡선 암호인 ECDHE(Elliptic Curve DHE)의 특징이다. RSA 키교환 알고리즘을 사용하게 되면 클라이언트가 대칭키(비밀키)를 생성하여 인증서 내부에 들어있던 서버의 공개키로 암호화 한 후 전달하게 된다.
클라이언트, 서버 모두가 서로에게 보내는 패킷으로 교환할 정보를 모두 교환한 뒤 통신할 준비가 다 되었음을 알리는 패킷이다. 그리고 ‘Finished’ 패킷을 보내어 SSL Handshake를 종료하게 된다.
여기까지가 SSL Handshake이다. 요약해보면 ClientHello(암호화 알고리즘 나열 및 전달) -> ServerHello(암호화 알고리즘 선택) -> Server Certificate(인증서 전달) -> Client Key Exchange(데이터를 암호화할 대칭키 전달) -> Client / ServerHello Done (정보 전달 완료) -> Finished(SSL Handshake 종료) 정도로 나열할 수 있다. 과정이 끝나면 클라이언트와 서버는 데이터를 암호화할 동일한 대칭키(비밀키)를 갖게 되며, 서로에게 각자 갖고 있는 동일한 대칭키를 통해 데이터를 암호화하여 전송하거나 데이터를 복호화한다. 클라이언트와 서버는 이제 성공적으로 비밀친구가 되었다.
HTTPS 통신과정에서 언급한 Cipher Suite를 다시 정리해보자
위의 그림이 Cipher Suite로 암호화 협상을 위한 알고리즘으로 무엇을 쓸 것인지 모아둔 것이다. SSL/TLS 프로토콜, 키 교환 방식, 인증서 검증, 블록 암호화 방식, 메시지 인증이 있다.
SSL Handshake의 기반이 되는 SSL/TLS 프로토콜의 버전을 의미한다. 보통 SSLv3, TLSv1.0, TLSv1.1, TLSv1.2 등이 있고 Cipher Suite에서는 SSL 혹은 TLS로 표기된다. ClientHello 패킷에서 ‘Version’ 항목을 통해 확인할 수 있다. 아래 캡처엔 TLS 1.0 임을 확인하실 수 있다.
최근에 Google Chrome에서 TLSv1.0, TLSv1.1의 지원을 종료하겠다는 발표가 있었다. 사용가능한 Version 중 TLSv1.0, TLSv1.1을 빼겠다는 뜻이 된다. 해당 버전의 프로토콜을 빼게 되면 해당 프로토콜과 연결된 Cipher Suite는 사용할 수 없다.
SSL Handshake의 목표이자 데이터를 암호화하는 실질적인 키인 대칭키(비밀키)를 서버에게 전달하기 위한 방법(알고리즘) 선택을 의미한다. 주로 ECDHE, RSA 등이 사용된다. 여기서 잠깐 짚고 넘어가야 할 것은 RSA와 Diffie-Hellman(DH)이다.
RSA 암호
공개키 알고리즘이다. 앞서 HTTPS 통신과정 2단계에서 한 쌍의 공개키와 개인키가 있다고 말했었다. 바로 각기 다른 키인 공개키와 개인키를 이용하여 암호화/복호화하는 알고리즘이다. 공개키로 암호화하여 개인키로 복호화하거나, 개인키로 암호화하여 공개키로 복호화한다. CA(Certificate Authority)가 자신이 발급한 인증서를 암/복호화하는데도 사용한다.
DH(Diffie-Hellman) 키 교환
RSA와는 약간 다른 알고리즘이지만 데이터를 암/복호화하기 위해 하나의 키를 쓰는 알고리즘이다. RSA가 공개키와 개인키를 생성하여 공개키를 모두에게 공개하는 것과 달리, DH 키 교환 알고리즘은 Parameter(매개변수), 즉 키를 생성할 재료를 교환한다. 매개변수는 공개적으로 교환하며 노출되어도 상관없다. 매개변수를 교환한 후, 클라이언트와 서버 모두 동일한 대칭키(비밀키)를 얻게 된다. 종류로는 DH, DHE(Diffie-Hellman Ephermeral), ECDHE(Elliptic Curve Diffie-Hellman Exchange)가 있다.
위에서 인증기관인 CA가 발급한 SSL 인증서에 서버가 발행한 공개키가 들어있다고 말했다. SSL 인증서에 서버의 공개키가 들어있다는 것은 서버가 대칭키(비밀키)를 암호화하기 위한 키 교환 알고리즘 선택시 RSA를 선택했다는 것을 의미한다. 왜냐하면 공개키가 있다는 것은 곧 서버가 공개키-개인키 쌍(RSA)을 생성하여 SSL 인증서 생성 시 공개키를 제출했기 때문이다. 다시 말해 공개키 암호 방식을 선택한 것이다. 그리고 SSL Handshake의 ‘Client Key Exchange’ 과정에서 사용자는 서버의 공개키를 이용해 대칭키(비밀키)를 암호화하고 서버에 전달하게 된다.
Diffie-Hellman(DH)를 선택하면 어떻게 될까? 위의 설명처럼 Diffie-Hellman(DH) 알고리즘은 공개키-개인키 쌍을 생성하지 않고 Key Parameter(키 매개변수)만을 교환하면 동일한 대칭키(비밀키)를 얻을 수 있기 때문에 SSL 인증서 내부에 서버의 공개키가 존재하지 않는다. 그리고 사용자와 서버는 SSL Handshake의 ‘Client Key Exchange’와 ‘Server Key Exchange’를 통해 서로 키 매개변수를 교환한다.
말그대로 인증서를 검증하기 위한, 인증기관인 CA가 발급한 SSL 인증서를 검증하기 위한 알고리즘을 선택한다. 여기서 검증이란 CA의 개인키로 암호화된 SSL 인증서를 CA의 공개키로 복호화하는 과정을 의미한다. SSL 인증서가 CA가 발급한 것이 맞다면 CA가 공개한 공개키로 인증서가 복호화될 것이다. 만약 인증서가 RSA 알고리즘으로 암호화되어있다면 당연 서버는 RSA 알고리즘이 담긴 Cipher Suite를 선택할 것이다.
HTTPS 통신과정은 데이터를 암호화하여 전송하기 위한 협의 과정이라고 말한 적 있다. ‘암호화 알고리즘'은 데이터를 실질적으로 암호화하기 위해 사용되는 알고리즘이다. 클라이언트와 서버가 공유하는 대칭키(비밀키)와 선택한 암호화 알고리즘(블록 암호화 방식)을 가지고 데이터를 암호화하게 된다. 블록 암호화 방식으로 불리는 이유는 데이터를 일정 길이의 블록으로 쪼개어 암호화하기 때문이다. 보통 암호화에 사용되는 대칭키(비밀키)의 길이가 길면 길수록 암호화의 강도가 강해지고 암호화/복호화에 사용되는 리소스 소모가 커진다. 이 키 길이는 어떤 암호화 알고리즘을 사용하느냐에 따라 달라진다. 암호화 알고리즘의 종류와 키 길이, 블록 길이는 다음과 같다.
또한 암호화 알고리즘은 ‘양방향’이라는 특성을 갖기 때문에 원본 데이터를 암호화 데이터로 암호화 할 수 있고 암호화 데이터를 원본 데이터로 복호화할 수 있다.
-> 주고받는 데이터를 위변조 확인하는 것은 MAC, 클라이언트-서버 전송할때는 세션키 사용, 초반에 랜덤해서 생성한 것을 세션키로 나중에 사용
암호화된 데이터를 서로 주고받는다 하더라도 이 데이터가 정말로 누군가의 조작에 의해 변했는지, 변하지 않았는지 알 수 없다. 이를 확인하기 위해 특정 알고리즘을 사용해 원본 데이터를 일정한 길이의 암호화된 문자열로 변경한다. 이 특정 알고리즘은 원본 데이터마다 일정한 결과값을 도출하며 원본 데이터가 변경되면 결과값 또한 달라지는 특성을 지닌다. 이 특정 알고리즘을 Hash 알고리즘(해시 알고리즘)이라고 부르며 해시 알고리즘이 적용된 암호화된 문자열을 Hash 값(해시값)라고 부른다. 해시 알고리즘의 종류에는 MD5, SHA-128, SHA-256 등이 있다. 아래 그림은 SHA-256 해시 알고리즘을 평문에 적용했을 때의 값을 나타낸 것이다. 같은 단어를 사용하였음에도 순서가 다르자 완전 다른 해시값이 나타나는 것을 알 수 있다.
송신자는 원본 데이터(암호화 알고리즘에 의해 암호화된)와 해시 알고리즘이 적용된 데이터를 함께 전송하고 수신자는 약속한 해시 알고리즘을 이용해 원본 데이터에 적용해본다. 해시 알고리즘이 적용된 원본 데이터가 상대방이 보낸 ‘해시 알고리즘이 적용된 데이터'와 결과가 같다면 이것은 변조되지 않은 메시지임을 알게 된다. 해시 알고리즘의 종류에는 MD5, SHA-128, SHA-256 등이 있다.
해시 알고리즘은 ‘일방향'이라는 특성을 갖기 때문에 해시 알고리즘이 적용된 결과값에서 원본 메시지로 되돌릴 수 없다는 특성을 지닌다. 다시 말해 해시값을 원본 데이터로 되돌릴 수 있다면 취약한 알고리즘임을 뜻하는 것이다.
여기서 암호화 알고리즘과 해시 알고리즘의 차이가 드러나는데, 암호화 알고리즘은 원본 데이터를 암호화할 수 있고 암호화된 데이터를 복호화하여 원본 데이터로 되돌릴 수 있지만 해시 알고리즘은 일방향 특성을 갖기 때문에 해시가 적용된 데이터를 원본 데이터로 되돌릴 수 없다.
https://aws-hyoh.tistory.com/34?category=768734
https://firework-ham.tistory.com/4
https://www.lesstif.com/ws/ssl-tls-https-43843962.html
https://aws-hyoh.tistory.com/39
https://aws-hyoh.tistory.com/47?category=768734