암호화는 전통적으로 소중한 정보를 지키는 방법으로 이용되어 왔습니다. 현대 암호화시스템에서는 RSA알고리즘, 인증서, 인증서 체인 등 복잡다단하게 암호화 통신을 하고 있지만 이렇게 발전하게 된 것은 그리 오래되지 않습니다.

2차세계대전에서 독일군은 현대 암호화의 전신인 독일군의 에니그마 (enigma) 라는 암호시스템을 이용하여 암호화 함으로써 연합군에서 도감청 하더라도 그 내용을 확인 할 수 없도록 하였는데,  튜링이라는 수학자가 이를 해독함으로써 연합군이 승기를 잡을 수 있게 되었죠. 영화 이미테이션 게임 에는 이런 튜링의 일화가 잘 나와 있습니다.

튜링은 에니그마가 가지는 여러 취약점을 이용하여 이 암호화 문제를 풀어내는데 이 영화를 보면 왜 블록암호 모드 같은 내용이 현대 암호시스템에 추가되어 만들어졌는지 잘 나타나 있습니다. 이와같은 사례가 잘 나와있으니 암호화 시스템의 원리와 발전을 이해하고 싶다면 꼭 보도록 합시다!

동성연애자에 성격파탄자이지만 인류를 구원해 낸 튜링

 

대칭키 암호화 (Symmetric key algorithm)

전통적으로 암호화는 대칭키를 이용한 암호화로 이루어져 왔습니다. 송신자는 암호화의 대상이 되는 중요정보가 담긴 평문 (Plain Text) 를 대칭키 (Symmetric Key) 로 암호화하여 암호문 (Encrypted Text) 수신자는 이 암호문을 동일한 대칭키로 복호화하여 그 내용을 볼 수 있는 시스템이였던 것이죠.

이러한 대칭키 암호화는 근본적인 문제점이 있는데 송신자와 수신자가 서로 동일한 내용의 대칭키를 이미 암호화가 시작되기전에 알고 있어야 한다는 것이죠. 따라서 이 대칭키를 쉽게 바꿀수도 없고 예전에는 대칭키를 우편 등을 통하여 공유 하는 등 구조적인 한계점을 가지고 있었습니다. 

보통 보안장비에서 Pre-Shared Key 로 표현되는 방식이 바로 대칭키 암호화 이며, 영문 그대로 미리 공유된 대칭키라는 의미를 가지고 있습니다. 

만약 대칭키를 엘리스와 밥이 서로 교환하려고 한다면 엘리스와 밥중 한명이 암호키를 만들어서 상대방에게 전달해야 합니다. 그런데 이런 암호키 전달과정에서 이브가 이 암호키를 가로챌 수 있으며 만약 이렇게 암호키가 누출되었을 경우에는 대칭키를 통한 암호화 통신을 엘리스와 밥 뿐 아니라 의도하지 않은 이브도 암호화 통신을 복호화 하여 그 내용을 확인 할 수 있게 되는 것이죠.

(한국 군대에서 주요내용을 전화를 이용하여 전달 할 때 암호표를 통하여 주요내용을 감청자가 모르게 치환하여 송수신자가 이야기 하게 되는데, 여기서 치환된 통화 내용은 암호문이고 암호표는 바로 대칭키라고 볼 수 있겠죠. 아시다시피 이 암호표는 사전 송수신자가 공유되어야 하고요)

이런 문제를 근본적으로 해결하고 암호키를 쉽게 전달하기 위해 나온 방법이 바로 비대칭키 암호화 (Asymmetric key algorighm) 입니다.

 

비대칭키 암호화 (Asymmetric key algorithm)

과거 대칭키 알고리즘을 이용하여 암호화를 진행하였을 때는 암호키 뿐만 아니라 알고리즘도 노출되지 않도록 노력하였습니다. 암호화 알고리즘과 암호키의 노출은 곧 암호가 깨졌다는 것을 의미하기도 하였죠. 하지만 현대의 암호화 방식은 암호 시스템의 모든 것 (시스템 구성 및 암호화 알고리즘) 이 모두 공개되어도 안전해야 한다는 관점을 가지고 있는데, 이것을 주장한 Kerckhoff 씨에 따라 Kerckhoff의 법칙이라고 합니다.

쉽게 말해 RSA 공개키 암호방식과 AES와 같은 암호화 알고리즘이 모두 공개되어 있지만 그 알고리즘을 통하여 만들어진 암호화 통신을 쉽게 복호화 시킬 수 없습니다. (수학적인 복잡성에 따라 복호화시간이 무한대로 걸려 복호화가 사실상 불가능 하죠. 물론 가끔가다 이를 깨버리는 미친 수학자들이 있습니다) 이를 Kerckhoff 법칙에 만족한다고 이야기 할 수 있습니다.  

그렇다면 Kerckhoff 법칙을 만족하면서 암호화에 사용될 키를 공유 할 수는 없을까요? 이것이 바로 우리가 SSL/TLS 에서 주로 사용하는 RSA 공개키 암호화 방식입니다.

로널드 라이베스트(Ron Rivest), 아디 샤미르(Adi Shamir), 레너드 애들먼(Leonard Adleman) 세명의 이름 (Surname) 의 첫글자를 따서 RSA가 됨

RSA 공개키 암호화 방식의 가장 큰 특징은 암호화 키가 한쌍이라는 것입니다. 다시 말해 열쇠가 두개라는 것이죠. 하나는 암호화 하는데 사용되고 다른 하나는 복호화 하는데 사용됩니다. 예를 들어 RSA 알고리즘을 통해서 A라는 열쇠와 B라는 열쇠가 생성되었다고 가정하면, A로 잠궈진 문은 B로만 열 수 있고, B로 잠궈진 문은 A로만 열 수 있다 라는게 RSA 알고리즘의 핵심 원리가 되겠습니다.

일반적으로 한쌍의 암호화 키 중 하나는 공개키, 다른 하나는 비밀키로써 공개키는 암호화에 쓰이고 비밀키는 복호화에 쓰여진다고 알려져 있으나 이는 잘못된 이해입니다. 비밀키로 암호화 된 것을 공개키로 복호화 하여 볼 수도 있고, 마찬가지로 공개키로 암호화 된 것을 비밀키로 풀어서 볼 수도 있습니다. 이러한 한쌍의 암호화 키를 이용하는 암복호화 방식이 바로 RSA 알고리즘 인 것이죠.

일반적으로 암호화에 사용될 대칭키를 전달 할 때, 이 대칭키를 RSA의 공개키로 암호화 하여 상대방에게 전달하고, 비밀키를 가지고 있는 상대방만 이 암호화 내용을 복호화 하여 대칭키를 알아내는 것이 SSL/TLS에서 RSA를 통해 대칭키를 공유하는 방식이 되는 것이죠. 이렇게 남몰래 공유된 대칭키를 이용하여 암호화 세션을 만들어 송수신자는 비밀스럽게 통신을 할 수 있게 되는 것이죠.

물론 공개키/비밀키를 이용하여 모든 통신을 암호화/복호화 하여 통신하면 좋겠지만 RSA의 비대칭키를 이용한 암호화 방식은 복잡한 수학적 원리로 이루어져 있으며, 이는 고스란히 CPU리소스를 소모하게 되지요. 따라서 대칭키를 공유 할 때만 RSA의 공개키/비밀키 방식으로 대칭키를 공유하고, 최종적으로 대칭키가 공유되면 CPU리소스를 덜 잡아먹는 대칭키로 암호화 하여 통신하게 되는 것이지요.

 

인증서 와 공개키의 무결성 검증이 필요한 이유

현재 우리가 사용하고 있는 브라우저에는 여러 인증서 들이 이미 포함되어 있습니다. 이 인증서 는 여러 인증기관 (CA, Certificate Authority) 에서 발행한 인증서 들이 포함되어 있는데 이러한 인증서 들은 SSL/TLS로 서비스되는 웹사이트에 접속하게 될 때 사용하게 될 공개키의 무결성을 검증하는데 사용됩니다. 

사용자가 rsec.kr 과 같은 SSL/TLS 기반의 웹사이트에 암호화 통신을 시도하게 될 때, 웹서버는 공개키가 포함된 인증서를 사용자에게 보내주어 이 공개키를 통하여 암호화 하면 된다고 알려줍니다. 하지만 이 공개키가 정말로 내가 접속하고자 하는 rsec.kr 에서 발송한 것인지 아니면 중간에 해커나 악의적인 사용자가 조작하여 발송한 것인지는 알 수 없습니다.

만약 해커가 인증서와 인증서에 포함된 공개키를 조작하여 유저에게 보내고 유저는 이를 신뢰하여 해커가 보내준 공개키로 암호화하여 통신을 시도하게 된다면 해커는 도감청이 가능할 것입니다. RSA의 탁월한 알고리즘의 원리와는 상관없이 말이죠. 하여 이렇게 수신받은 인증서와 공개키가 정말 믿을 만한 것인지를 확인하는 과정이 꼭 필요합니다. 이 때 사용되는 것인 인증서 체인 (Certificate Chain) 입니다. 

 

해쉬와 디지털 서명 (Hash and Digital Signing)

앞서 RSA 알고리즘을 이용해서 공개키/비밀키가 생성된다고 했습니다. 여기서 우리는 암호화 통신을 이용하여 통신 할 때 사용할 1쌍의 키중 공개키를 사용자들에게 공개하게 되는데, 이 공개키가 내가 발행한 것 (rsec.kr에서 발행한 것) 을 보증받기 위해 인증기관 (CA) 에 공개키를 등록하게 됩니다. 

이는 마치 우리가 인감도장을 만들어서 동사무소에 인감을 등록하는 것과 비슷합니다. 인감도장의 내용을 동사무소에 등록하면 동사무소는 이것이 내가 발행한 인감이라는 것을 보증하여 줍니다. 마찬가지로 내가 발행한 공개키 (인감도장, 인증서) 을 인증기관 (동사무소, CA) 가 보증해주게 되는 원리인 것입니다. 

여기서 인증기관 (동사무소, CA) 가 나의 공개키 (인감, 인증서) 를 보증하기 위해서 서명을 하게 되는데, 여기서 서명이란 나의 공개키가 해쉬된 값 (SHA256 등으로 해쉬된 값) 을 인증기관의 비밀키로 암호화 한 결과값을 디지털 서명이라고 하는 것입니다. 쉽게 설명하면

  1. 공개키에 대해서 (해쉬 한 후) 인증기관의 비밀키로 암호화 함
  2. 역으로 인증기관 (CA) 에서 발행한 공개키로 이 디지털 서명값을 복호화 하면 인증서에 대한 해쉬값을 얻을 수 있음
  3. 인증서 에 등록되어 있는 해쉬값과 인증기관에서 발행한 공개키로 서명값을 복호화 해서 나온 해쉬값이 서로 동일하면 인증서의 내용과 공개키가 위변조 되지 않았음을 보증 할 수 있음

인증서 에는 다양한 정보들이 포함되어 있지만 그중에서 중요한 정보들은 다음과 같습니다. 

  • 발급대상 (issued, 예를 들어 rsec.kr)
  • 발급대상의 공개키 (rsec.kr 의 공개키)
  • 발급자 (issuer, rsec.kr의 인증서 를 발행한 인증기관)
  • 발급자의 서명 (issuer sigining, rsec.kr의 인증서를 발행한 인증기관의 디지털 서명)

이러한 인증서의 주요정보를 모아 SHA256등의 해쉬 알고리즘을 이용하여 해쉬 합니다. 이렇게 해서 나온 해쉬값을 인증서의 Finger Print (지문) 이라고 합니다. 이러한 지문내용을 인증서에서 보면 아래와 같습니다.

이렇게 해쉬알고리즘으로 생성된 해쉬값인 Finger Print (지문) 을 발급자 (issuer) 인 인증기관 (CA)은 인증기관이 소유하고 있는 비밀키로 암호화 한 후, 그 결과값을 발급자 서명 (Digital Signing) 으로 등록합니다. 인증서에서의 내용은 아래와 같습니다.

이렇게 나온 서명값을 상위 인증기관의 공개키로 복호화 하게 되면 facebook.com의 Finger Print (지문) 값인 해쉬값이 나오게 되는데, 이 둘이 동일하면 인증서와 공개키의 무결성이 상위 인증기관의 비밀키를 통해 보증되는 것이죠.

요 공개키를 이용하여 하위 인증서의 서명을 복호화하며, 이 복호화 한 결과값이 fingerprint (지문) 된 해쉬값과 동일하면 인증서의 무결성이 보장된다

이런식으로 상위 인증기관이 하위 인증서가 포함하고 있는 공개키 (인증서) 를 상위기관의 비밀키로 암호화 하여 상호 보증하게 되는데 이것을 인증서 체인 (Certificate Chain) 이라고 부릅니다.

이 인증서 체인을 통하여 최종 인증서는 중계기관 (Intermediate CA) 이 보증해주며, 중계기관의 인증서는 루트 인증기관 (Root CA)가 보증해주게 됩니다. 루트 인증기관은 상위 인증기관이 없기 때문에 셀프 사인 (스스로 보증) 하게 됩니다. 

그리고 우리가 일반적으로 인증기관 (CA)와 상관없이 발행하는 사설인증서는 셀프사인 (자신의 인증서를 해쉬한 후, 자신의 비밀키로 해쉬를 암호화하여 사인으로 등록) 하기 때문에 보증하는 인증기관이 없으며, 따라서 누구도 보증해주지 않는 신뢰 할 수 없는 인증서가 되는 것이지요.

이런식으로 연결된 인증서 체인의 원리는 요즘 한창 회자되고 있는 블록체인의 원리와 동일합니다. 해쉬하고 내용을 상대편 기관에서 사인하여 보증하게 되는 것이지요

 

이렇게 인증서는 암호화 할 공개키가 포함되어 있고, 이 공개키의 무결성을 검증하기 위해 상위기관과 서명으로 연결되어 무결성을 보증하도록 구성되어 있습니다. 이러한 최종 공개키를 검증하기 위한 루트 인증기관 (Root CA), 중계기관 (Intermediate CA) 의 공개키들은 브라우저와 피씨에 이미 포함되어 있는 것이구요. (맥의 경우에는 키체인에 있습니다~)

끝까지 읽어주셔서 감사합니다~

 

  • dodam

    좋은 글 감사합니다.
    한가지 질문이 있습니다.
    악의적인 해커가 가짜 root CA 정보를 만든 후, 이것을 웹브라우저에 심는 방식의 공격은 있을 수가 없나요?
    풀어쓰면 다음과 같습니다.
    악의적인 해커가 어떤 피씨에 악성코드를 심었다고 합시다. 이 악성코드는 2가지 기능을 합니다.
    첫번째, 해당 피씨의 웹브라우저에 가짜 root CA 정보를 심습니다.(다시 말해, 해커는 미리 비대칭키쌍을 하나 만들어 두고, 이 키쌍을 마치 root CA의 것인냥 사용할것입니다. 이렇게 허구로 만든 가짜 root CA 정보를 웹브라우저에 심는겁니다.) 두번째, 특정 웹사이트로의 연결을 속여서 가짜 fishing 사이트로 연결되게 합니다.
    이 해커는 가짜 fishing 사이트 SSL/TLS 연결에 사용할 비대칭키쌍도 만들어놓습니다. 뿐만 아니라 위에서 말한 가짜 root CA 공개키로 인증된 인증서도 만들어놓습니다.
    이런 상황이라면, 감염된 피씨를 사용하는 유저가 특정 웹사이트에 연결하면, 가짜 피싱 사이트로 연결이 되고, 피싱 사이트는 공개키 및 인증서를 웹브라우저에게 알려줄 것입니다.
    감염된 피씨의 웹브라우저는 이 공개키 및 인증서의 무결성을 검증하려할겁니다. 웹브라우저의 root CA 정보가 오염되지 않은 경우라면, 이 무결성 검사는 실패하게 될것입니다. 하지만 이미 악성코드에 의해서 웹브라우저의 root CA 정보는 공격당했습니다. 즉, 웹브라우저에는 허구의 root CA 정보가 이미 들어있기 때문에, 무결성 검사는 통과할것입니다. 따라서 웹브라우저와 피싱 사이트 사이에는 SSL/TLS 연결이 이루어지게 될것이고, 유저는 특별히 이상한점을 쉽게 눈치채지 못할겁니다.
    …. 라는 시나리오가 떠오르는데요.
    이런게 가능한가요? 아니면 제가 공개키의 무결성 검증 방식을 잘못 이해한건가요?

    • SLoVey

      지나가다가 제 생각도 정리하면 좋을겸해서 댓글드립니다.
      말씀하신 공격은 아래에 답변주신것처럼 충분히 가능합니다만,
      HTTPS 통신을 공격 (공개키의 무결성 검증을 공격) 한것은 아니라고 생각됩니다.
      왜냐면 이미 다른 공개키를 사용하고 있는 것이기 때문이지요.
      그 다른 공개키에 대해서는 말씀하신 공개키의 무결성 검증을 잘 통과한것입니다.

      그리고 한가지 더 답변 드리면, ROOT CA 목록이 오염되지 않더라도 공개키 무결성 검증에는 성공합니다.
      해쉬를 이용한 공개키에 대한 수정이 없었음을 증명해주는 것과, 이 증명해주는 기관이 신뢰성이 있다는 것은 조금 다른 관점입니다.

  • jroh

    간단하게 말씀드려서 말씀하신 시나리오는 가능 합니다. 이미 사례도 있구요.

    일반적으로 웹사이트 연결시 상대편 사이트에서 제공해주는 공개키가 공인된 것인지를 확인하기 위해 웹브라우저에 있는 Root CA인증서를 이용하게 됩니다. 이 Root CA는 웹브라우저나 PC에 OS가 설치될 때 함꼐 들어있는 놈이구요.

    하지만 굳이 해커가 아니더라도 사설 Root CA를 기업용 PC에 배포 할 수 있다면 웹브라우저에서는 안전함으로 표시되며 알 수 없는 인증서라고 표시되지 않습니다. 해커가 위 작업을 진행할 수 있다면 (AD등으로 인증서를 배포하는 등) 당연히 안전함 표시와 함꼐 피싱사이트로 유도 될 수 있습니다.

    let’s encrypt 같은 공공 SSL발급기관을 이용하여 피싱사이트를 안전함으로 표시하면서 공격한 사례가 있습니다.
    https://scotthelme.co.uk/lets-encrypt-are-enabling-the-bad-guys-and-why-they-should/

    감사합니다.

  • killaz

    아…너무 정리가 잘되어 있네요.
    대박입니다. 감사합니다.!