네트워크와 보안

서정범·2024년 1월 15일
0

네트워크

목록 보기
26/26

개요

여기서 다룰 내용은 네트워크: 하향식 접근에서 8장에 해당하는 "컴퓨터 네트워크 보안" 챕터에서 나오는 내용들입니다.

필요한 내용은 추가하고, 복잡한 개념은 풀어서 정리를 하겠습니다.

시작하기 앞서

송수신자가 메시지를 전송하는 과정은 인터넷 네트워크를 통해서 이루어진다는 것을 앞에서 확인했습니다.

또한, 송수신자의 장치들이 직접 연결되어서 통신하는 것이 아니라 중간에 패킷 전송 장치들의 도움을 받아서 전송되는 것도 확인을 하였습니다.

메시지는 물리 매체와 패킷 전송 장치들을 통해서 전송된다고 볼 수 있습니다.

따라서, 이 과정에서 누군가가 패킷을 도청한다면(탈취) 중요한 정보들이 노출될 수 있습니다.

이것을 위해서 네트워크 보안이 필요한 것입니다.

여기서는 네트워크 보안을 위해서 적용하는 암호화 기술들에 대해서 알아볼 것이고, 적용되는 과정에 대해서 알아볼 것입니다.

네트워크 보안이란

네트워크 보안에 요구되는 사항들은 다음과 같습니다.

  1. 기밀성: 도청자가 해석할 수 없도록 메시지를 어떠한 방식으로 암호화해야 한다.
  2. 메시지 무결성: 신뢰성 있는 전송 및 데이터 링크 프로토콜을 위해 사용했던 체크섬(checksum) 기술을 확장함으로써 메시지 무결성을 제공할 수 있다.
  3. 종단점 인증: 송신자와 수신자는 통신에 참여하는 상대방이 실제 누구인지 확인하기 위해 상대방의 신원을 확인할 수 있어야 한다.
  4. 운영 보안: 기관들의 내부 네트워크는 공공 인터넷에 연결되어 있다. 이 네트워크들은 외부로부터 공격을 받을 수 있는 잠재적 위험이 있기 때문에 기관 네트워크를 보호하기 위해 사용되는 방화벽이나 침입 감지 시스템이 필요할 수 있다.

이러한 요구 사항들을 위해서 필요한 암호화에 대해서 알아보겠습니다.

암호화

여기서 데이터 형식과 관련하여 자주 나오는 용어들이 있는데 이것들을 정리하고 넘어가겠습니다.

먼저, 다음과 같은 것들이 있습니다.

  • 암호화/복호화
  • 인코딩/디코딩
  • 직렬화/역직렬화
  • 서명

각각의 용어들이 어떠한 개념인지 먼저 정의를 적어보겠습니다.

  • 암호화/복호화

    1. 암호화: 코딩된 알고리즘, 해시, 서명 사용을 통해 정보를 보호하는 방식을 말합니다.
    2. 복호화: 암호화된 정보를 암호화 되기 전 형태로 바꾸는 것을 의미합니다.
  • 인코딩/디코딩

    1. 인코딩: 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 위해서 다른 형태나 형식으로 변환하는 것을 의미합니다.
    2. 디코딩: 인코딩된 정보를 인코딩 되기 전 형태로 바꾸는 것을 의미합니다.
  • 직렬화/역직렬화

    1. 직렬화: 데이터 구조나 오브젝트 상태를 동일하거나 다른 컴퓨터 환경에 저장하고 나중에 재구성할 수 있는 포맷으로 변환하는 과정이다.
    2. 역직렬화: 직렬화되어 있는 데이터를 저장되어 있는 데이터 구조나 오브젝트 상태와 매칭하여 이전 구조의 형태로 돌려놓는 것을 의미합니다.
  • 서명

    1. 서명: 누군가가 문서에 기록했다는 증거, 자기 동일성을 위한 표시를 하기 위해 쓴 것을 말합니다.
    2. 전자 서명: 서명자를 확인하기 위해, 특정 전자문서에 첨부되거나 논리적으로 결합된 전자적 형태의 정보를 말합니다.

4가지 모두 데이터의 변환을 위해 사용하지만 목적성이 다릅니다.

암호화/디코딩은 데이터의 보안을 위해서,
인코딩/디코딩은 주고 받는 방식의 표준화 혹은 성능 개선을 위해서,
직렬화/역직렬화는 오브젝트를 주고 받기 위해서,
서명은 메시지의 인증(무결성)을 위해서 사용합니다.

크게 4가지의 개념들 정리했지만, 필자는 여기서 인코딩/디코딩, 직렬화/역직렬화에 대해선 다루지 않을 것입니다.

자세하게 다룰 내용은 암호화/디코딩과 서명입니다.

암호의 원리

암호화와 복호화에서 중요한 것은 "키"입니다.

만약, 모든 이들이 동일한 방식으로 암호화와 복호화를 수행한다면 그것은 비밀 정보라고 보기 힘들 것입니다.

따라서, 앞으로 나올 암호화 알고리즘에는 "키"가 매개변수로써 작용을 할 것이고, 매개 변수에 따라 출력값이 변화한다는 점을 알아둬야 합니다.

"키"를 사용하는 방식에는 다음과 같은 방식이 있습니다.

  1. 대칭키 시스템: 메시지를 암호화/복호화할 때 사용하는 키가 동일
  2. 비대칭키 시스템: 메시지를 암호화할 때 사용하는 키와 복호화할 때 사용하는 키가 다르다.

여기서 비대칭키 시스템에서 사용 방식이 다른 두 키를 다음과 같이 부릅니다.

  1. 공개키: 세상 전체에 공개되어도 크게 문제가 안된다.
  2. 비공개키: 본인만 알고 있어야 한다.

비대칭키 시스템에서 특히, 비공개키가 어디에 사용하는지에 따라 암호화인지 서명인지 나뉠 수 있기 때문에 주의해서 살펴봐야합니다.

비공개키를 사용하는 것이 중요한 목적을 가진 행위를 수행하는 동작이 되어야 합니다.

암호화를 사용하는 목적은 무엇일까요?

누군가가 암호화된 데이터를 훔쳐가더라도 데이터를 해석할 수 없도록 하기 위함에 있습니다.

즉, 이것은 데이터를 훔쳐가는 것을 예방하는 것이 아니라 데이터를 훔쳐가더라도 누구나가 해석하지 못하도록 하는데에 목적이 있습니다.

그렇다면 암호화 과정이 중요할까요? 아니면 복호화 과정이 중요한 것일까요?

암호화/복호화 과정에서는 복호화 과정(수신자측)에 비밀키가 사용됩니다.

서명의 경우, 메시지의 인증에 목적이 있습니다. 즉, 누구나가 해당 메시지를 만들 수 없도록 하는데에 목적이 있습니다.

그러므로 서명은 송신자측에서 비밀키가 사용됩니다.

대칭키의 원리

가장 쉬운 대칭키 암호 방식으로는 단순 문자 매칭으로 생각할 수 있습니다.

즉, 일정한 표를 가지고 문자를 매칭하던가 아니면 특정한 규칙을 통해서 문자 변환을 수행하는 방식들이 존재합니다.

대표적으로 다음과 같은 방식이 있습니다.

  • 카이사르 암호(Caesar ciphter)
  • 단일 문자 대응 암호(monoalphabetic ciphter)

하지만 해당 방식들은 다음과 같은 취약점을 가지고 있습니다.

  • 암호문을 이용한 공격(ciphtertext-only attack): 평문 메시지의 내용에 대한 어떠한 사전 정보도 없이 가로챈 암호문에만 접근할 수 있는 경우
  • 알려진 평문 공격(known-plaintext attack): 암호문 메시지에 확정적으로 나올 것 같은 단어를 선택하여 그것을 포함하는 평문과 암호문의 쌍을 대략적으로 결정
  • 선택 평문 공격(chosen-plaintext attack): 침입자가 미리 알고있는 문장이 담긴 평문 메시지를 선택하여 이에 대응하는 암호문 형태를 얻는 방식.

단일 문자 대응 암호는 나중에 다중 문자 대응 암호로 발전하여 하나의 평문 문자가 여러개로 매칭될 수 있는 방식으로 향상되게 됩니다.

이것은 반복 형식, 예를 들어 C1, C2, C1, C2와 같이 매칭되도록 하는 방식, 을 사용하여 가능하도록 구현됩니다.

현재에 대칭키 암호화 기술은 크게 두가지로 나뉩니다.

  • 스트림 암호(Stream ciphers)
  • 블록 암호(block ciphers)

블록 암호화에 대해서 다룰 것인데,

블록 암호화에서는 메시지가 "k비트"의 블록 단위로 암호화됩니다.

이것을 테이블로 기록해두고 매칭하는 형태로 동작합니다.

이후 이것을 더 작은 청크 단위로 쪼개서 매칭한 후 섞어서 암호화를 수행합니다.

예를 들어, k가 64라고 할 경우, 64비트 블록을 8비트씩 8개의 청크(chunk)로 나눕니다.

테이블을 이용한 매칭 비트의 크기는 크게보면 64비트지만, 그것을 더 작게 나눠서 8비트로 하여 8개만 매칭에 사용하는 것입니다.

또한, '청크'의 위치에 따라 다른 테이블을 사용합니다. 변환을 한 후 정해져 있는 규칙에 따라 청크를 뒤섞어서 붙인 후 암호화된 64비트 블록을 만듭니다.

해당 방식도 취약점이 존재하는데 동일한 평문 블록에 대해서 블록 암호화 기법은 같은 암호문을 생성해 낸다는 점입니다.

이것을 위해서 임의성(randomness)를 추가할 수 있습니다.

임의성 비트블록을 추가하여 평문 블록을 암호화 할 수 있고, 임의성 비트 블록을 암호화된 비트블록에 붙여서 복호화할 때 사용하도록 함으로써 중복된 암호화 블록 생성을 막을 수 있습니다.

하지만, 이와 같이 할 경우 오버헤드가 추가되기 때문에 암호 블록 체이팅(CBC, Ciphter BLock Chaning)이라는 기법을 이용합니다.

기본 아이디어는 첫 번째 메시지와 함께 임의의 수를 단 한번만 전송하고 이후의 임의의 수로 직전에 계산된 암호문 블록을 대신 사용하는 것입니다.

이때 사용하는 임의의 수를 초기화 벡터(IV, Initialization Vector)이라고 합니다.

비대칭키 암호화

공개키 암호화는 암호화/복호화가 같은 키로 이루어 진다는 것이라고 했습니다.

그렇다면, 송수신자는 해당 키를 공유할 수 있어야 하는데 어떻게 해야할까요?

일반적으로 생각하면 직접 "키"를 공유하는 것을 생각할 수 있습니다. 하지만, 원격 통신을 통해 공유를 해야한다면 이것 또한 보안상 위험할 수 있습니다.

그래서 비대칭키를 사용하는 것입니다.

비대칭키에서 중요한 것은 다음과 같습니다.

  • 두 키의 관계: 비대칭키 암호화에서는 공개키와 개인키라는 두 개의 수학적으로 관련된 키가 사용됩니다. 이 두 키는 서로 다르지만, 특정 수학적 관계에 의해 연결되어 있습니다.
  • 암호화 알고리즘: 이 시스템에서는 하나의 키(예: 공개키)를 사용해 데이터를 암호화하고, 다른 하나의 키(예: 개인키)를 사용해 데이터를 복호화합니다. 공개키는 모두에게 공개될 수 있지만, 개인키는 소유자만이 알고 있어야 합니다.
  • Modulo-n 연산: 비대칭키 암호화 알고리즘중 일부(예: RSA)는 modulo-n 연산을 기반으로 합니다. 이는 큰 정수를 다루는 곱셈, 나눗셈 및 거듭제곱과 같은 연산을 포함하며, 이러한 연산은 역산하기 매우 어려워 보안을 제공합니다.

RSA 알고리즘의 경우 공개키 암호화와 거의 동의어처럼 취급됩니다.

RSA는 modular-n 연산을 많이 사용하는데, 핵심적인 부분은 이것입니다.

비공개키를 사용해서 만든 암호화된 데이터를 공개키를 사용해서 계산하면 원래의 데이터가 나옵니다.

이것은 어떠한 성질에 의한 것인데,

[(a mod n) · (b mod n)] mod n = (a · b) mod n

이 성질로부터 다음과 같은 항등식을 얻을 수 있습니다.

RSA에 필요한 지수 연산은 시간이 많이 필요한 작업입니다.

반면에, DES(Data Encryption Standard)는 소프트웨어로 구현했을 떄 이보다 최소한 100배 빠르고, 하드웨어로 구현된 것은 1,000~10,000배 빠릅니다.

따라서 RSA는 실제로 종종 대칭키 암호화와 함께 사용됩니다.

이것을 세션키(session key)라고 하는데, 다음과 같이 사용될 수 있습니다.

  1. 먼저, 서버가 암호화 알고리즘을 통해서 비밀키 생성 및 공개 키 생성을 수행합니다.
  2. 공개키를 공유하고 클라이언트는 공개키를 받아서 필요한 정보를 생성하고 공개키로 암호화 해서 공유합니다.
  3. 주고 받은 모든 정보를 이용해서 세션키를 각각 생성 후 이것을 통해 데이터 암호화/복호화 작업을 수행합니다.

이 기본적인 플로우는 나중에 정리할 SSL/TLS의 기본적인 동작이 될 것입니다.

메시지 무결성과 전자서명

메시지의 무결성은 다음과 같은 것들이 재대로 지켜져야 합니다.

  1. 메시지가 정말 송신자로부터 온 것인가?
  2. 수신자에게 전달되는 도중에 메시지가 변경되지는 않았는가?

여기서는 암호화 해시 함수에 대한 개념이 등장하는데 간단하게 정리하자면 다음과 같습니다.

데이터를 해시 함수를 이용해서 해싱하여 다른 출력 문자를 만들어 냅니다. 또한 시간에 상관없이 입력값이 같다면 같은 출력값을 반환합니다.

이것은 암호화/복호화는 다르게 특정 "키"를 사용해서 수행하는 것이 아니기 때문에 기본적으로는 복호화 작업이 불가능합니다.

그렇다면 이것을 어떻게 이용할 수 있을까?

예를 들어서 설명하자면 다음과 같은 곳에서 사용할 수 있습니다.

  1. 송신자는 메시지 m을 생성하고 해시 H(m)을 계산합니다.
  2. 송신자는 메시지 m에 H(m)을 첨부하여 확장 메시지(m, H(m))을 생성한 후 수신자에게 보냅니다.
  3. 확장 메시지(m, h)를 받은 수신자는 H(m)을 계산합니다. 만일 H(m) = h라면, 수신자는 모든 것이 문제없이 처리되었다고 결론지을 수 있습니다.

즉, 송신자로부터 온 메시지인지 확인하는 작업이 가능하다는 것입니다.

메시지 무결성을 위해서는 암호화 해시 함수의 사용 외에도 송신자와 수신자가 비밀키를 공유할 필요가 있습니다.

비트열 형태인 이 공유 비밀키는 인증키(authentication key)라고 불립니다.

  1. 송신자는 메시지 m을 생성한 후 s와 접합하여 m + s를 만듭니다. 그 다음 해시 H(m + s)를 계산하 내는데, 이것을 메시지 인증 코드(MAC, message authentication code)라고 부릅니다.
  2. 송신자는 MAC을 메시지 m에 첨부하여 확장 메시지 (m, H(m + s))을 생성해서 수신자에게 보냅니다.
  3. 수신자는 확장 메시지 (m, h)를 받으면 이미 알고 있는 s를 이용하여 MAC H(m + s)를 계산합니다. 만일 H(m + s) = h라면, 수신자는 아무 문제가 없다고 결론 짓습니다.

여기서 중요한 점은, 메시지의 무결성은 보장하지만 기밀성은 보장하지 않는다는 점입니다.

이것은 암호화를 수행하기 위한 것이 아닌 송신자로부터 온 메시지가 맞는지에 목적이 맞춰져 있다는 점을 잊지 말아야합니다.

전자서명

전자서명(digital signature)은 디지털 세계에서 서명의 목적으로 사용되는 암호화 기법입니다.

이 방식으로 앞서 보았던 MAC을 고려해볼 수 있습니다.

자신의 고유 비밀키를 메시지에 첨부하고 이를 해시 함수에 넣어서 만들어진 MAC을 서명으로 쓰는 방법을 고려해 볼 수 있는 것이다.

그러나 수신자가 서명을 확인하기 위해서는 그 키의 복사본을 가지고 있어야 하고, 따라서 키가 송신자만의 고유한 비밀이 될 수 없는 문제가 있습니다.

따라서 MAC은 전자서명으로 적합하지 않습니다.

서명의 목적은 송신자의 신원 확인이 목적이므로 데이터를 암호화하는 과정이 중요합니다.

따라서, 서명은 일반적인 암호화/복호화와 다르게 수신자가 아닌 송신자가 비밀키를 사용하고 수신자는 공개키를 사용합니다.

앞서 말했지만 암호화/복호화는 연산이 과중하다는 단점을 가지고 있습니다.

이것을 위해서 해시 함수를 전자서명에 이용할 수 있습니다.

해시 함수를 수행하여 송신자는 메시지 자체가 아니라 "메시지의 해시 결과"에 서명을 하는 것입니다.

공개키 인증

마지막으로 공개키를 사용할 때 주의할 점에 대해서 언급하고 넘어가자.

공개키를 공유를 할 때 수신자는 해당 공개키가 송신자로부터 온 키임을 확신할 수 있는가?

공개키를 사용할 때 주의할 점은 공개키가 "통신 개체의 것"인지 확인할 수 있어야 한다는 점이다.

이것을 보증하는 일은 전형적으로 인증기관(CA, Certification Authority)에서 담당하는데, 이들이 하는 일은 신원을 확인하고 인증서를 발행하는 것이다.

CA의 역할은 다음과 같다.

  1. CA는 어떤 개체가 스스로 주장하는 자신의 신분, 바로 그 개체가 맞는지 확인한다.
  2. 일단 CA가 개체의 신원을 확인하면, CA는 그 개체의 공개키아 신분확인서를 결합한 인증서를 만든다. 이 인증서는 공개키와 함께 이 공개키의 주인에 대한 고유한 식별 정보를 담고 있다.

종단점 인증

여기서는 종단점 인증(end-point authentication)에 관련해서 다루는데, 종단점 인증이란 하나의 다른 개체에게 자신의 신원을 컴퓨터 네트워크상으로 증명하는 작업을 의미합니다.

인증 프로토콜(authentication protocol)이라 부르는 여러 가지 버전의 인증 프로토콜에 대해서 설명하는데 간단하게만 정리할 것이다.

  • ap 1.0: 메시지를 통해 인증
  • ap 2.0: IP주소를 통해 인증
  • ap 3.0: 비밀번호를 통해 인증
  • ap 3.1: 암호화된 비밀번호를 통해 인증

위의 버전들은 여전히 위험한 취약점들을 가지고 있습니다.

따라서, 여기서는 ap 4.0에 대해서 소개합니다.

ap 4.0은 넌스(nonce)라는 고유한 숫자를 사용한 방식을 의미합니다.

다음과 같이 사용한다고 볼 수 있습니다.

  1. 송신자는 수신자에게 통신 요청을 보냅니다.
  2. 수신자는 넌스 R을 선택하고 그것을 송신자에게 보냅니다.
  3. 송신자는 서로의 대칭 비밀키를 사용해서 그 넌스를 암호화하고, 암호화된 넌스를 수신자에게 보냅니다.
  4. 수신자는 자신이 받은 메시지를 복호화합니다. 만약 복호화한 넌스가 송신자에게 보낸 넌스 값과 일치한다면 신원 인증이 완료됩니다.

당연히, 비밀 대칭키를 사용하는 방식은 보안상 위험할 수 있기 때문에 좀 더 복잡한 절차를 거쳐 공개키 방식을 사용합니다.

⚡️ 보안 기능이 여러 계층에서 수행되는 이유? ⚡️

  1. 보안을 위협하는 행위가 특정 계층에서만 발생할 것이라고 확정할 수 없기 때문입니다.
  2. Application 수준에서 보안을 제공하는 것은 여러 개발자들에게 쉬운 접근성과 확장성을 제공해주기 때문입니다.

TCP 연결의 보안: SSL

SSL(Secure Sockets Layer)은 향상된 TCP 버전을 의미합니다.

SSL 버전 3의 약간 변형된 버전이 TLS(Transport Layer Security)입니다.

SSL의 기본 동작은 TCP를 보호하는 것이기 때문에 TCP 상에서 일어나는 어떠한 응용에도 사용 가능합니다.

SSL/TLS 핸드셰이크 과정은 TCP 3-way handshakes가 이루어 진 후 일어납니다.

  1. 암호화 알고리즘 협상
    • 클라이언트 헬로: 클라이언트는 서버에게 'ClientHello' 메시지를 보냅니다. 이 메시지에는 클라이언트가 지원하는 암호화 알고리즘들의 목록(암호 슈트), SSL/TLS 버전, 랜덤 데이터, 그리고 선택적으로 세션 ID가 포함됩니다.
    • 서버 헬로: 서버가 'ServerHello' 메시지로 응답합니다. 이 메시지에는 선택된 암호화 알고리즘, SSL/TLS 버전, 랜덤데이터, 세션 ID가 포함됩니다.
  2. 서버의 공개키 전달
    • 서버 인증: 서버는 클라이언트에게 자신의 공개키가 포함된 디지털 인증서를 보냅니다. 이 인증서는 신뢰할 수 있는 제 3자(CA)에 의해 발급되며, 서버의 신원을 보증합니다. (이 과정은 'ServerHello' 메시지 응답과 같이 이루어집니다.)
  3. 프리마스터 시크릿 생성 및 교환
    • 프리마스터 시크릿 생성: 클라이언트는 프리마스터 시크릿이라는 임시 키를 생성합니다.
    • 프리마스터 시크릿 암호화 및 전송: 클라이언트는 서버의 공개키를 사용하여 프리마스터 시크릿을 암호화하고, 이 암호화된 키를 서버에게 전송합니다.
  4. 세션키 생성
    • 세션키 계산: 서버와 클라이언트는 둘 다 앞서 교환된 랜덤 데이터와 프리마스터 시크릿을 기반으로 같은 세션키를 "독립적"으로 생성합니다.
  5. 암호화된 세션 시작
    • 암호화 통신: 클라이언트와 서버는 이제부터 이 세션키를 사용하여 통신 데이터를 암호화하고 복호화합니다.

여기서 추가적으로 수행되는 것은 이후에 누군가가 메시지를 탈취하고 수신자에게 송신자인 척 그대로 메시지를 보낸다면(재활용) 응답을 그대로 받을 수 있습니다.

따라서, 넌스를 포함시켜서 각 TCP 연결마다 서로 다른 넌스를 사용하게 함으로써 암호화 키가 변경하면서 문제를 해결할 수 있습니다.

참고한 자료

  • 컴퓨터 네트워크: 하향식 접근
profile
개발정리블로그

0개의 댓글