HTTPS를 알아보자

sloth·2020년 8월 4일
2

HTTPS

HTTPS란?

HTTP의 보안상 취약한 부분을 강화한 프로토콜이 바로 HTTPS(HyperText Transfer Protocol over Secure Socket Layer)입니다.

HTTP는 리소스를 암호화하지 않은 상태로 전송하기 때문에 제 3자에 의해 감청당하거나 데이터 변조와 같은 보안문제가 일어날 가능성이 있습니다. HTTPS는 SSL(Secure Socket Layer)라 불리는 프로토콜 위에서 동작하여 HTTP의 보안상 취약점을 보완해 리소스를 전송합니다.

참고로 HTTP는 well-known 포트로 80번을 사용하지만, HTTPS는 443번을 사용합니다.

SSL을 설명하기 앞서...

SSL 동작과정을 이해하기 위해서는 알아야 할 몇 가지 개념들이 있습니다. 이들을 먼저 살펴보고, SSL이 어떻게 동작하는지 자세히 살펴보겠습니다.

대칭키 암호화(Symmetric Key Cryptography)

대칭키 암호화(비밀키 암호화)는 평문을 암호화할 때, 반대로 암호문을 복호화할 때 사용하는 키(Key)가 동일한 암호화 방식을 말합니다.

대칭키 암호화 방식은 데이터를 변환하는 방식(알고리즘)에 따라 블록암호와 스트림암호로 구분됩니다.

블록 암호

출처: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

평문 데이터를 특정 길이(N)의 비트들로 쪼개서 블록 단위로 만들고, 이렇게 쪼개진 블록들을 암호화하는 방식입니다. 블록암호에는 운용 방식(mode)이라는 것이 있습니다. 운용 방식은 쪼개진 블록들을 어떻게 암호화할 것인지 결정하는 요소입니다. ECB, CBC, CFB 등 여러 방식이 있지만, 여기서 설명하는 것은 주제에서 벗어나므로 자세한 설명은 생략하겠습니다.

대표적인 블록 암호화 방식으로는

  • DES(Data Encryption Standard) / DES3(3중 DES)
  • AES(Advanced Encryption Standard)

스트림 암호

출처: https://thisismyclassnotes.blogspot.com/2017/05/cryptography-stream-ciphers-and-its.html

의사난수(Pseudorandom) 스트림을 만들어서, 평문 데이터와 결합(보통은 xor 연산을 사용)하여 암호화하는 방식입니다. 의사난수 스트림은 keystream이라 불리며, 이를 어떻게 생성하느냐에 따라 동기식과 비동기식으로 나뉘지만, 주제에서 벗어나므로 자세한 설명은 생략하겠습니다.

대표적인 스트림 암호화 방식으로는

  • RC4

장/단점

  • 암/복호화 시 사용하는 키의 크기가 상대적으로 작고 암호화 알고리즘의 내부 구조가 단순하여 공개키 암호화 방식에 비해 속도가 빠릅니다.
  • 하지만 통신 당사자간 키가 공유해야 하기 때문에 키를 관리하는 데 어려움이 발생합니다. (잦은 키 변경, 당사자간 키 분배 문제)

공개키 암호화(Public Key Cryptography)

출처: https://www.brainkart.com/article/Principles-of-Public-Key-Cryptosystems-and-its-Applications,-Requirements,-Cryptanalysis_8435/

대칭키 암호화 방식과 달리, 공개키 암호화(비대칭키 암호화) 방식은 평문을 암호화할 때와 암호문을 복호화할 때 사용하는 키가 서로 다른 암호화 방식입니다. 즉, 두 가지의 키를 사용하는 방식입니다.

하나는 타인에게 제공되는 공개키(Public Key)이고, 다른 하나는 자신만이 가지는 개인키(Private Key, 비밀키, 비공개키)입니다. 공개키로 암호화한 것은 개인키로 복호화할 수 있고, 개인키로 암호화한 것은 공개키로 복호화할 수 있습니다. 공개키로 암호화된 내용은 개인키가 유출되지 않는 한 복호화할 수 없기 때문에, 공개키는 아무리 노출되더라도 안전합니다.

공개키 암호화 종류

  • RSA => 엄청 큰 정수를 소인수분해하는 것이 매우 어렵다는 점을 이용.
  • Rabin => 중국인의 나머지 정리(Chinese Remainder Theorem, CRT)을 이용.

장/단점

  • 상술했듯이, 공개키는 아무에게나 노출돼도 상관없는 키이기 때문에 키 관리 문제가 쉽게 해결됩니다.
  • 암/복호화를 할 때, 수학적인 성질을 이용하기 때문에 대칭키 암호화 방식보다 엄청 느립니다.

해시함수와 MAC(Message Authentication Code)

해시함수

출처: https://networkencyclopedia.com/hashing-algorithm/

해시함수란, 임의의 길이를 가진 메시지를 일정 길이(n 비트)의 메시지롤 변환하는 함수를 말합니다. 해시함수의 출력결과로 나오는 n 비트의 메시지를 해시값(Hash value 혹은 다이제스트, Digest)라 부릅니다.

(암호학에서의) 해시함수는 단방향성이며, 단방향성이란 해시값으로부터 원본 메시지를 역산할 수 없다는 특징을 가집니다.

대표적인 해시함수는

  • MD5
  • SHA-*(Secure Hash Algorithm) => SHA-1, SHA-256, SHA-512

하나의 원본 메시지는 단 하나의 해시값을 갖지만, 반대로 하나의 해시값은 여러 개의 원본 메시지를 가질 수 있습니다. 서로 다른 메시지가 동일한 해시값을 가지면 이를 충돌(Collision)이라 부릅니다. 보통 해시함수는 메시지의 무결성을 검증하는데 많이 사용하기 때문에, 충돌 가능성 최소화하는 것은 해시함수에게 매우 중요한 요소입니다.

MAC(Message Authentication Code, 메시지 인증 코드)

말 그대로 메시지를 인증할 때 사용하는 코드를 의미합니다. MAC은 해시함수를 활용하여 전달받은 메시지의 송신자가 정상적인 사용자인지 인증합니다.

출처: https://en.wikipedia.org/wiki/Message_authentication_code

송신자와 수신자가 같은 키, 같은 MAC 알고리즘을 공유하고 있다고 가정합니다.

위 방식은 MAC 알고리즘을 해시함수를 사용하는 HMAC 방식입니다.

  1. 송신자는 메시지를 보내기 전에, MAC 알고리즘(보통 해시함수)에 키와 메시지를 입력하여 MAC 값을 만듭니다.
  2. 메시지와 MAC을 수신자에게 함께 보냅니다.
  3. 수신자는 전달받은 메시지와 미리 공유하고 있던 키를 MAC 알고리즘에 입력하여 MAC를 만듭니다.
  4. 수신자는 자신이 만든 MAC과 송신자가 보낸 MAC이 같은지 비교합니다. 만약 같다면, 정상적인 사용자가 보냈다고 판단합니다.

전자서명(Electronic Signature)

실세계의 서명과 동일하다고 생각하면 됩니다. 다만, 서명의 대상이 서류가 아닌 전자적인 데이터이고 서명을 펜으로 하지 않는다는 점이 다르겠네요. 서명을 통해 서명자의 신원을 확인하고, 서명한 서류의 내용을 서명자가 승인하였음을 나타낼 수 있습니다.

출처: https://en.wikipedia.org/wiki/Electronic_signature

전자서명은 크게 두 가지 과정이 있습니다. 데이터를 서명하는 과정(1 ~ 2)과 서명을 검증하는 과정(3 ~ 4)입니다.

참고로 위 과정은 디지털 서명로 구현된 전자서명입니다.

  1. 송신자는 서명 알고리즘(Signing algorithm)을 통해 보낼 메시지에 서명을 합니다. 보통 서명 알고리즘은 위 그림과 같이 원본 메시지를 해시함수에 입력하여 해시값을 만듭니다. 그 후, 송신사의 개인키를 이용해 암호화합니다.

  2. 이렇게 암호화된 해시값(서명)을 원본 메시지 끝에 첨부하여 전자서명된 데이터를 만듭니다. 그리고 이를 수신자에게 전송합니다.

  3. 수신자는 전자서명된 데이터를 메시지와 서명으로 분리합니다. 메시지는 (서로 공유하고 있는) 해시함수에 입력하여 해시값(A)를 만듭니다. 그리고 서명은 송신자의 공개키를 통해 복호화(B)합니다.

  4. A와 B를 비교하여 서명이 정상적인지 판단합니다. 같다면, 서명이 정상적인 것입니다.

SSL/TLS

일단 SSL과 TLS은 같은 말이다. SSL이 넷스케이프에 의해 만들어지고 관리되다가 표준화 기구인 IETF(Internet Engineering Task Force, 국제 인터넷 표준화 기구)에게 넘어가면서 TLS(Transport Layer Security)라는 이름으로 변경되어 관리되고 있다.

SSL Handshake

출처: https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/

  1. 클라이언트가 서버에 접속한다. Client Hello단계라 불리며, 이 때 클라이언트는 서버에게 다음과 같은 정보를 보낸다.

    • SSL버전

    • 클라이언트에서 생성한 랜덤 데이터(난수)

    • 클라이언트가 지원하는 암호화 방식 (Cipher suites)

      • 이 정보를 보내는 이유는 상호 간 어떠한 암호화 방식을 사용할 것인지 협상하기 위해서입니다. 왜냐하면 서버와 클라이언트가 지원하는 암호화 방식의 차이가 있을 수 있기 때문입니다.

      • 협상해야할 암호화 알고리즘은 4가지입니다.

        • 대칭키 교환에 사용할 암호화 알고리즘

          • 실제 데이터를 암호화할 때 사용할 대칭키(Session key)를 교환할 때 사용할 알고리즘를 말합니다.
          • 보통 공개키 암호화 알고리즘을 사용합니다.
          • RSA, DH, DHE, ECDH, ECDHE 등
        • 인증서 서명 알고리즘

          • 클라이언트가 서버로부터 받은 인증서를 전자서명을 통해 검증할 때 사용할 알고리즘을 말한다.
          • 보통 서버가 인증서를 발급받을 때 CSR(인증서 서명 요청)을 하는데, 이 때 선택한 알고리즘을 선택한다.
          • RSA, ECDSA, DSA 등
        • 대칭키 알고리즘

          • 실제 데이터를 암호화할 때 사용할 대칭키(Session Key) 암호화 알고리즘을 말합니다.
          • 대칭키 암호화 알고리즘이 블록 암호일 경우, 블록 암호 운용 방식을 설정해야 합니다.
          • AES, ARIA, 3DES 등
        • MAC 알고리즘

          • 보통 HMAC 방식을 사용합니다.
          • SHA-1, SHA-256, MD5 등
          • Session key와 암호화된 메시지를 협상한 해시 알고리즘에 입력하여 MAC을 생성하고, 이를 암호화된 메시지와 함께 보냅니다.
          • 수신자는 전달받은 암호화된 메시지와 session key를 협상한 해시 알고리즘에 입력하여 MAC을 생성하고 이를 전달받은 MAC과 비교하여 데이터 무결성을 검증합니다.
    • 세션 아이디 (optional)

      • 이미 SSL handshaking을 했다면 시간과 비용을 줄이기 위해 기존 세션을 재활용하게 되는데, 이때 사용할 세션 아이디를 전송합니다.
  2. 서버는 Client Hello단계에 대한 응답으로 Server Hello 절차를 수행합니다. 이 때 서버가 클라이언트에게 건네는 정보는 다음과 같습니다.

    • 서버가 지원하는 SSL 버전
    • 서버에서 생성한 랜덤 데이터(난수)
    • 서버가 선택한 암호화 방식
      • 1번 단계에서 클라이언트가 보낸 암호화 방식 중 서버가 사용할 수 있는 암호화 방식을 선택하고 이에 대한 정보를 클라이언트에게 보냄으로써 협상을 종료합니다.
    • CA로부터 발급받은 인증서
  3. 클라이언트는 서버로부터 받은 인증서를 검증한다.

    • 인증서를 발급한 CA가 자신의 CA리스트에 존재하는 지 확인.
    • 해당 CA의 공개키로 인증서가 복호화되는 지 확인.
  4. 인증서가 정상적으로 검증되었으면, 클라이언트는 pre master secret라 불리는 랜덤 데이터를 하나 생성합니다. 인증서에 담겨있는 서버의 공개키를 이용해 pre master secret을 암호화하고 서버에게 전송합니다.

  5. 클라이언트로부터 받은 pre master secret을 서버 자신의 개인키로 복호화합니다. 이로써 pre master secret을 서버와 클라이언트가 모두 공유합니다. 서버와 클라이언트는 PRF(PseudoRandom Function) 알고리즘으로 pre master secret을 master secret 값(48bytes)으로 만듭니다.

    master_secret = PRF(pre_master_secret, "master secret",
    		ClientHello.random + ServerHello.random)[0..47];
  6. 이렇게 만든 master secret를 통해 session key를 생성하고, 서버와 클라이언트는 Session key를 사용하여 대칭키 암호화 방식으로 데이터를 암호화하여 통신합니다.

    key_block = PRF(SecurityParameters.master_secret,
                    "key expansion",
                    SecurityParameters.server_random +
                    SecurityParameters.client_random);
    client_write_MAC_key[SecurityParameters.mac_key_length]
     server_write_MAC_key[SecurityParameters.mac_key_length]
     client_write_key[SecurityParameters.enc_key_length]
     server_write_key[SecurityParameters.enc_key_length]
     client_write_IV[SecurityParameters.fixed_iv_length]
     server_write_IV[SecurityParameters.fixed_iv_length]
  7. 서버와 클라이언트 handshake 단계의 종료를 서로에게 알립니다.

세션

세션 단계는 실제 서버와 클라이언트가 데이터를 주고 받는 단계입니다. 위에서 언급한 것처럼 Session key를 사용하여 대칭키 암호화 방식으로 데이터를 암호화하여 통신합니다

세션 종료

데이터 전송이 끝나면 SSL 통신이 끝났음을 서로에게 알려주고, 이 때 통신에서 사용한 대칭키인 session key를 폐기합니다.

문제점

  • 서버와 클라이언트의 신원을 확인하는 데 인증서를 사용되며, 인증서의 신뢰성은 이를 발급한 인증기관에 의해 결정됩니다. 만약 인증기관 자체가 문제가 있다면 해당 기관에서 발급한 인증서를 신뢰할 수 없게 됩니다.
  • HTTP보다는 느릴 수 밖에 없다. 왜냐하면 SSL 통신을 위해 위에서 언급한 Handshake 단계가 수반되고, 데이터를 송수신할 때 암/복호화 과정을 거치기 때문에 이로 인한 부하가 발생하기 때문입니다.

참고

0개의 댓글