보안 연결 수립 과정 즉, SSL/TLS의 HandShaking과정은 꽤나 복잡하다. 이를 보면서 느끼는 것은, 왜 굳이 이렇게까지 연결을 진행할까? 이며, 이에 대한 답은 해커들의 중간자 공격으로 스니핑 또는 스푸핑 등의 공격을 하기 때문이다.
[스니핑 공격]
네트워크 상, 돌아다니는 데이터를 감청하는 행위를 말한다. 이를 통해 해커는 사용자의 계정 비밀번호, 계좌번호 등 민감한 정보를 알 수 있게 된다.
[스푸핑 공격]
해커가 네트워크 상, 피해자의 IP주소/MAC주소 변환 작업 후, 피해자의 패킷을 탈취 및 왜곡시키는 행위를 말한다. 해당 행위로 해커는 웹사이트에 윤리적으로 옳지 못한 요청으로 자신의 이득을 취하게 된다. 대표적인 예로 계좌에서 돈이 빠져나가는 등의 경우가 있다.
보안 공격의 경우의 수는 많다. 하지만 한 가지 공통된 사실은 네트워크상 돌아다니는 패킷의 내용을 해커가 볼 수 있다는 것이다. 이를 방지하는 1가지 솔루션으로 PKI인증 방식이 있다.
PKI인증은 Public Key Infrastructure의 약자이다. 이는 공개키 기반 시설이라는 의미를 담고 있는데, 그 의미에 맞게 웹 상에 자유롭게 배포된 공개키를 사용하여 인증하는 방식을 의미한다. 이때 만들어진 공개키는 보안적으로 신뢰할 수 있는 상위 인증 기관에 의하여 만들어지며, 이러한 요소들을 사용하여 안전하게 인증하는 방식을 PKI인증 방식이라 한다.
인증서는 생성 시, 대략적으로 아래의 정보를 포함한다.
- 인증서 소유자 이름
- 인증서 만료 기간
- 인증서의 공개키
- 위 1,2,3의 정보를 해시한 인증서 해시값
- 개인키
하지만 빠진 것이 하나 있다. 바로 인증서의 해시값을 서명한 값이 없다는 것인데, 이는 사설 인증서에 해당하며 아직 신뢰할 수 없다는 것이다. 하지만 특정 개인키로 서명한 인증서의 경우, '서명된 해시값'이 들어가게 된다.
- 인증서 소유자 이름
- 인증서 만료 기간
- 인증서의 공개키
- 위 1,2,3의 정보를 해시한 인증서 해시값
5. 해시값을 서명한 서명값- 개인키
하지만 서명값을 어디로부터 받았는지가 중요하다. 자신이 서명한 인증서라면 이는 '사설 인증서'에 해당한다. 따라서 신뢰할 수 없을 가능성이 크다. 하지만 만약 서명한 개인키의 소유주가 세계적으로 인정하는 Root CA라면 어떨까? ROOT CA라는 곳은 세계적으로 보안상 신뢰할 수 있는 곳이다. 따라서 이 곳에서 만든 사설 인증서는 공인 인증서로써의 기능이 가능하며 신뢰할 수 있다고 볼 수 있다.
따라서 SSL HandSking과정을 알아보기 전, 그에 대한 준비 작업인 공인 인증서의 2가지 생성 경우를 먼저 알아본다.
PKI인증을 위해선 공인 인증서 준비작업이 필요하다. 이때, 공인 인증서를 만드는 데에는 2가지 방식이 있다. 한 가지는 ROOT CA가 자체적으로 공인 인증서를 만드는 방식인데, 이 기관은 세계적으로 안전하다고 약속한 ROOT기관인 만큼 상위 인증기관이 존재하지 않는다. 따라서 공인 인증서를 생성하며 만들어지는 '서명된 해시값'은 Self-Sign을 통해 만들어지게 된다.
네이버와 같은 웹 사이트를 들어가고 인증서 구조를 보면 위와 같은 3단계인걸 볼 수 있다. 가장 위에 존재하는 인증서가 ROOT CA에서 발급한 공인 인증서에 해당한다. 그리고 그 밑에 존재하는 인증서는 Intermediate CA즉, ICA에서 발급한 공인 인증서를 의미하며 그 밑의 naver의 경우는 ICA로부터 발급한 인증서를 의미한다. 지금 알아볼 단계는 2, 3단계에서의 인증서 발급 방법이다.
ROOT CA는 말 그대로 최 상위 ROOT이기에 상위 인증기관이 없다. 다만, 그 밑의 경우는 다르다. 이들은 공인 인증서를 발급받는데 있어, 상위 인증기관이 보유한 개인키로 서명하게 된다. 따라서 아래와 같은 그림대로 각각의 공인 인증서가 만들어지게 된다.
이제 공인 인증서가 만들어 졌으니, 이를 사용해 어떻게 안전한 인증이 이루어지는지 살펴보자. 아래와 같이 왼쪽에는 클라이언트가 네이버에 접속을 하려고 한다. 그럼 이때, 네이버는 클라이언트에게 ICA를 포함한 본인 서버의 인증서를 주게 된다.
이렇게 받은 인증서로 체인 검증을 시작한다. 하지만 위 그림만 보아선 뭔가 이상해보이기도 한다.
ICA의 서명된 해시값은 어떻게 검증할까?
바로, 클라이언트에 내장된 ROOT인증서와 공개키를 통해 가능하다. 아래와 같이, 웹 브라우저나 핸드폰에서 찾아보면 ROOT CA의 인증서가 있다는 것을 쉽게 알 수 있다.
즉 ICA의 '서명된 해시값'을 검증할 ROOT인증서는 클라이언트의 웹 브라우저에 이미 내장되어 있으므로 네이버로부터 응답받은 인증서만으로 검증이 가능하다는 것이다. 그럼으로써 아래 그림의 흐름대로 체인 검증이 진행된다.
위의 과정대로 체인 검증이 완료되면 클라이언트는 서버를 신뢰할 수 있게된다. 그럼 다음 할 일은 네이버가 클라이언트를 신뢰하는 일이다. 하지만 이 방식은 TLS의 버전이 1.2냐, 1.3이냐에 따라 달라지며 각각 RSA방식, ECDHE방식이라고 한다.
RSA방식은 추후 소개할 ECDHE방식에 비해 더 간단하다. 하지만 단점은 네이버의 개인키가 탈취되었을 경우, 해커의 공격으로 PMS값이 누출될 수 있다는 것이다.
RSA방식이든, ECDHE방식 모두 공통적으로 진행되는 SEED교환 작업이 존재한다. 아래 그림과 같이, 클라이언트와 네이버는 각각 Seed값을 교환한다.
그 후, 클라이언트는 내부적으로 PMS값을 생성하며, 이를 네이버 인증서의 공개키로 암호화한 후, 네이버로 전달한다.
위 그림의 과정을 거치게 되면 클라이언트와 네이버는 모두 동일한 세 가지 값인 client seed, server seed, encrypted PMS을 보유한다. 이제 이를 토대로 서버는 클라이언트가 신뢰할 수 있는지를 확인하는 과정이 필요하다. (아래 그림 참고) 이는 네이버가 자체적으로 보유한 개인키로 encrypted PMS를 복호화하는것이며, 만약 복호화 성공 시, encrypted PMS값이 신뢰할 수 있는 클라이언트라는 것을 증명된다.
위 과정을 통해 클라이언트와 네이버는 서로를 신뢰할 수 있게 되었다. 그리고 보안상 안전하게 동일한 값들을 보유하게 되었다. 그럼 지금부터 해당 값들을 조합하여 대칭키를 각각 생성하게 되며, 이를 통해 상호간 안전한 데이터 송수신이 가능하게 된다.
이는 클라이언트와 웹서버가 각각 공개키/개인키를 생성한다. 위 1번의 RSA방식의 경우, 웹 서버의 개인키가 탈취되었을 때 문제가 발생했지만, 이 방식은 클라이언트의 개인키 또한 탈취되어야 하므로, 1번에 비해 더 안전하다고 볼 수 있다. 즉, 해커가 일을 2번 해야만 한다.
또한 해당 방식은 타원곡선 스칼라의 곱
이라는 연산에 기반을 두고 있다. 이 글을 쓰는 필자는 수학적 공식/원리까진 자세히 알지 못하므로 개략적인 흐름만 설명한다.
우선 첫 번째로 클라이언트와 네이버는 각각 비대칭키를 생성한다. 그 후, 서로간 공개키를 교환한다.
위 과정을 통해 아래의 재료를 보유하게 된다.
- 클라이언트 : 자신의 개인키와 서버의 공개키
- 서버 : 자신의 개인키와 클라이언트의 공개키
따라서 위의 재료를 통해 각자 동일한 대칭키를 생성하게 되고, 이를 통해 안전한 보안 통신이 가능하게 된다.
[동일한 대칭키가 어떻게 만들어지지?]
위에서도 말했다시피 이는 타원곡선 스칼라의 곱
에 따른 수학적 공식에 근거한다. 필자는 해당 사항까진 모른다. 그래도 CHAT GPT에게 물어본 결과 아래의 답변을 주었다.
위 답변에 의하면, 첫 번째로 공개키는 개인키와 공통 타원 곡선G
라는 값으로 만들어진다. 그에 따라서 서로에게 A, B값을 공유하는데, 이는 각각 a * G
와 b * G
를 교환한 것과 같다. 그렇게 되었을 시, 클라이언트와 서버는 결국 아래의 과정을 통해 PMS를 계산하는 격이다.
a * b * G
b * a * G
위 두 공식을 동등성 비교를 해보면, 동일한 값인 G는 지워진다. 따라서 a * b = b * a
만 남게되는데, 이는 곱셈의 교환법칙에 의거하여 동일한 값이된다. 따라서 위 ECDHE의 방식에 따라 공통 대칭키를 생성하는 것이 의사적으로 납득이 된다.
대칭키 암호 알고리즘을 사용하여 클라이언트와 서버가 어떻게 안전한 통신을 하는지 알아보았다. 해당 글을 통해 도움을 받았다면 기분이 좋을것 같다.
[참고]