>Backouts_
Published on

TLS 시리즈 04: AES 모드(Mode) 이해해보기 🕶️

Authors
  • avatar
    Name
    Backouts
    Twitter

서론

블로그에 글을 쓴 지
거의 일주일 정도가 지났네요.

곧 오프라인 교육을 시작하게 되어
이사를 준비하고, 원룸을 계약하고,
짐을 싸는 데에 생각보다 많은 시간을 쓰게 되었습니다.

지난 글에서 AES에 대해 간단하게 알아봤지만
사실 AES는 단독으로 사용되지 않습니다.

AES를 실제 환경에서 안전하게 사용하기 위해서는
몇 가지 규칙과 방식이 함께 필요하고,
이것을 AES 모드(Mode) 라고 부릅니다.

오늘은 TLS 시리즈의 본격적인 내용으로 들어가
AES 모드에 대해 이야기해보려고 합니다.

만약 AES 자체에 대한 내용이 아직 익숙하지 않다면
아래 글을 먼저 읽고 오셔도 좋습니다.

[TLS 시리즈 03: AES 이해해보기]


AES를 그냥 사용하면 안되나? ❓

AES를 그냥 사용하면 어떻게 될까요?

지난 글에서 우리는 AES
128비트(16바이트) 단위로 암호화하는
블록 암호(Block Cipher) 라는 것을 배웠습니다.

즉, 통신에 사용되는 매우 긴 데이터는
한 번에 암호화되는 것이 아니라,
여러 개의 블록으로 잘려서 처리됩니다.

예를 들면 하나의 긴 데이터는
[data 1] | [data 2] | [data 3]
와 같은 형태로 나뉘어 순서대로 암호화됩니다.

실제로 이런 방식으로
각 블록을 독립적으로 암호화하는 방법이 존재하는데,
이를 ECB(Electronic Codebook) 모드라고 부릅니다.

ECB 모드
AES가 등장하기 이전부터 존재하던
가장 단순한 블록 암호 사용 방식입니다.

예시를 들어보겠습니다.

평문: "Hello Backouts, Welcom To My Blog"
블록: ["Hello Backouts, "], ["Welcom To My Blo"], ["g" + 패딩 15자리]
암호 로직: e -> z, 홀수 짝수 순서바꾸기
암호화: ["zHll oaBkcuost ,"], ["zWclmo T oyMB ol"], ["4g44444444444444"]

이 방식의 문제는
같은 입력 블록에 대해 항상 같은 암호문 블록이 생성된다는 점입니다.

즉, 입력 데이터에 반복되는 패턴을 넣으면
암호문에도 그 패턴이 그대로 남게 됩니다.

이런 암호문을 반복해서 보다 보면
공격자는 점점 구조와 규칙을
유추할 수 있게 됩니다.

이러한 문제를 해결하기 위해 등장한 것이
바로 AES 모드(Mode) 입니다.

AES 모드
각 블록을 독립적으로 암호화하지 않고,
블록들 사이에 관계를 만들어
패턴이 결과에 드러나지 않도록 설계된 방식
입니다.


AES 모드의 종류 ✔️

AES 모드의 종류는 정말 많지만,
그중에서도 대표적인 모드 3가지
간단하게 알아보려고 합니다.

CBC (Cipher Block Chaining) 모드

CBC 모드의 가장 큰 특징은
이전 암호문 블록을 다음 암호화 과정에 섞는다는 점입니다.

이런 구조 때문에
앞선 블록의 암호화 결과가 달라지면,
그 이후 블록들의 암호화 결과도
연쇄적으로 달라지게 됩니다.

예시를 들어보겠습니다.

평문: "Hello Backouts, Welcom To My Blog"
블록: ["Hello Backouts, "], ["Welcom To My Blo"], ["g" + 패딩 15자리]

위에 ECB 모드 설명에서 사용했던 예제를 그대로 들고왔습니다.

IV = 랜덤한 (128 비트)
K = 비밀키(128 비트)

C1 = AES(K, ["Hello Backouts, "] XOR IV)
C2 = AES(K, ["Welcom To My Blo"] XOR C1)
C3 = AES(K, ["g" + 패딩 15자리] XOR C2)

CBC 모드에서는
암호화를 시작하기 전에
IV(Initialization Vector) 라는
랜덤한 값(128비트)을 하나 생성합니다.

이 IV는
첫 번째 평문 블록과 XOR 되어
암호화 과정에 사용됩니다.

암호화 흐름을 간단히 표현하면 다음과 같습니다.

  • C1 = AES(K, 첫 번째 평문 블록 XOR IV)
  • C2 = AES(K, 두 번째 평문 블록 XOR C1)
  • C3 = AES(K, 세 번째 평문 블록 XOR C2)

이처럼 CBC 모드에서는
이전 암호문 블록이
다음 평문 블록과 XOR 되어
사용되기 때문에,

같은 평문 블록이더라도
앞선 암호문이 달라지면
완전히 다른 결과가 나오게 됩니다.

이를 통해
ECB 모드에서 발생하던
패턴 노출 문제를 해결할 수 있습니다.

CBC 모드의 한계

하지만 CBC 모드 역시
완벽한 방식은 아닙니다.

CBC 모드
암호문의 무결성을 검증하기 위해
먼저 복호화 과정을 수행
해야 합니다.

이 복호화 과정에서 발생하는
시간 차이나 오류 응답을 이용한
패딩 오라클(Padding Oracle) 공격
취약하다는 문제가 있습니다.

이러한 이유로
CBC 모드는 점차 사용이 줄어들었고,
현대의 TLS 환경에서는
더 안전한 모드들이 주로 사용됩니다.


CTR (Counter) 모드

CTR 모드
AES를 데이터를 직접 암호화하는 도구가 아니라,
키스트림을 생성하는 도구로 사용합니다.

즉, AES를 이용해
추측하기 어려운 바이트 열을 만들고,
그 결과를 평문과 XOR 하는 방식입니다.

CTR 모드에서 사용되는 요소는 다음과 같습니다.

  • K: 비밀키
  • nonce: 랜덤 값
  • counter: 블록의 인덱스
  • || : 값의 연결
    (예: 12바이트 || 4바이트 = 16바이트)

CTR 모드에서는
nonce와 counter를 연결해
128비트(16바이트) 입력 값을 만들고,
이를 AES에 넣어 키스트림을 생성합니다.

키스트림 생성 과정은 다음과 같습니다.

키스트림 = AES(K, nonce || counter)

여기서 생성된 키스트림은
비밀키와 연관은 있지만,
외부에서 예측하기는 매우 어려운
특수한 비트열
입니다.

CTR 모드의 암호화 방식

CTR 모드의 암호화 과정은 단순합니다.

  • nonce는 하나의 암호화 과정 동안 고정
  • counter는 블록마다 증가

이를 이용해 다음과 같이
각 블록에 대응되는 키스트림을 생성합니다.

  • 키스트림 1 = AES(K, nonce || 0001)
  • 키스트림 2 = AES(K, nonce || 0002)
  • 키스트림 3 = AES(K, nonce || 0003)

그리고 각 키스트림을
해당 인덱스의 평문 블록과 XOR 하면
암호화가 완료됩니다.

이 구조 때문에 CTR 모드
AES스트림 암호처럼 동작하게 됩니다.

CTR 모드의 장점

CTR 모드
각 블록이 서로 독립적으로 처리되기 때문에
병렬 처리가 가능하고,
속도가 매우 빠르다는 장점이 있습니다.

또한 패딩이 필요 없기 때문에
CBC 모드에서 문제가 되었던
패딩 오라클 공격과는 구조적으로 무관합니다.

CTR 모드의 한계

CTR 모드의 가장 큰 한계는
무결성을 제공하지 않는다는 점입니다.

즉, 암호문이 전송 중에 변조되더라도
수신자는 이를 감지할 수 없습니다.

또한,
같은 키와 같은 nonce를 재사용할 경우
동일한 키스트림이 생성
되며,
이로 인해 암호가 즉시 깨질 수 있습니다.

이런 이유때문에
CTR 모드는 단독으로 사용되기보다는,
무결성 검증이 함께 제공되는 방식과
결합되어 사용되는 경우가 많습니다.


GCM (Galois/Counter Mode)

GCM
앞에서 살펴본 CTR 모드의 방식에
무결성 검증 기능을 추가한 모드입니다.

CTR 모드
AES를 키스트림 생성기로 사용해
빠르고 효율적으로 암호화를 수행할 수 있었지만,

암호문이 전송 중에 변조되었는지에 대해서는
아무런 검증을 하지 못한다는 한계
가 있었습니다.

즉,
암호문이 중간에서 조금이라도 바뀌더라도
수신자는 이를 알지 못한 채
복호화를 시도하게 됩니다.

이런 문제를 해결하기 위해
GCM 모드
암호문과 함께 무결성 태그(Authentication Tag)
같이 생성하고 전송합니다.

GCM에서 무결성은 어떻게 사용될까?

GCM 모드에서는
암호문과 무결성 태그가
함께 전송
됩니다.

수신자는 데이터를 받으면
곧바로 복호화를 수행하지 않고,
먼저 무결성 태그가 올바른지 검증합니다.

만약 전송 중에
암호문이 단 한 글자라도 변경되었다면,
무결성 태그 검증에 실패하게 됩니다.

이 경우
데이터는 즉시 폐기되며,
복호화 과정은 아예 수행되지 않습니다.

이 점이
CTR 모드GCM 모드
가장 큰 차이점입니다.

왜 TLS에서는 GCM을 사용할까?

GCM 모드는

  • CTR 방식의 장점인 빠른 성능과 병렬 처리
  • 패딩이 없어 패딩 오라클 공격과 무관한 구조
  • 암호문 변조를 감지할 수 있는 무결성 검증

이 세 가지를 모두 만족합니다.

이러한 이유로
현재 TLS 환경에서는
AES-GCM 방식이
사실상 표준처럼 사용되고 있습니다.

후기

정리하자면,
AES는 블록 암호이기 때문에
데이터를 블록 단위로 나누어 암호화를 수행합니다.

하지만 블록 암호의 특성상
이 방식을 그대로 반복해서 사용하면,
ECB 모드처럼
암호문에 패턴이 드러나는 문제가 발생할 수 있습니다.

그래서 블록들을 서로 엮어
입력과 출력의 관계를 추측하기 어렵게 만드는
규칙이 필요했고,
이것이 바로 AES 모드(Mode) 입니다.

TLS에서는
이러한 모드들 중에서도
AES-GCM 방식을
사실상 표준처럼 사용하고 있습니다.

글로 정리해놓고 보니
내용 자체가 복잡해 보입니다.

하지만 ECB → CBC → CTR → GCM 순서로
각 방식의 단점과,
그 단점을 해결하기 위해 등장한 다음 방식을
차례대로 살펴보면서 공부하니
훨씬 이해가 잘 되었습니다.

물론
수학적인 부분은 최대한 빼고 말이죠…

다음 글에서는
AES-GCM 방식을 직접 구현해보려고 합니다.