>Backouts_
Published on

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

Authors
  • avatar
    Name
    Backouts
    Twitter

서론 😐

한동안 블로그 글을 올리지 못했네요
최근 듣고 있는 교육과정에서 프로젝트를 진행중이라
시간이 잘 안났습니다.

그래도 그 와중에도 시간을 내서 AES에 대해 조금씩 공부를 했고
해당 내용을 정리해볼까 합니다.


AES란? 🤔

AES는 현재 가장 널리 사용되는 대칭키 암호화 알고리즘입니다.

대칭키 암호라는 말은,
지금까지 사용했던 RSA와는 다르게,
암호화와 복호화에 같은 키를 사용한다는 의미입니다.

즉, 어떤 데이터를 AES로 암호화했다면.
같은 키를 가지고 있어야만 원래 데이터로 복호화할 수 있습니다.

AES의 특징

  • 블록 암호(Block Cipher)
    • 데이터를 일정한 크기(128비트) 블록 단위로 나누어 암호화합니다.
  • 가변적인 키 길이
    • 128비트, 192비트, 256비트 키 길이를 지원합니다.
  • 속도가 매우 빠름!
    • 비대칭키(RSA)에 비해 속도가 매우 빠릅니다.

AES는 왜 빠를까? 🔎

AES가 빠른 이유는 RSA와 다르게
복잡한 수학적 연산이 필요하지 않기 때문입니다.

[TLS 시리즈 02: RSA로 키 교환해보기]

RSA를 구현할 때는 큰 소수의 곱셈과 모듈러 연산 등
복잡하고 시간이 많이 걸리는 연산이 필요했습니다.

그래서 대용량 텍스트를 암호화하는데 적합하지 않다고 했었죠.

반면에 AES는 복잡한 수학 문제를 푸는 방식이 아니라,
데이터를 조금씩 섞고 바꾸는 단순한 작업을
여러 번 반복
하는 방식으로 동작합니다.

예를 들면,

  • 데이터를 일정한 규칙에 따라 다른 값으로 바꾸기
  • 데이터의 위치를 조금씩 섞기
  • 키 값을 이용해 한 번 더 섞기

이런 작업들을 여러 번 반복합니다.

그리고 이 과정들은 모두
컴퓨터가 아주 빠르게 처리할 수 있는 연산들입니다.

그래서 AES
대용량 데이터를 암호화하는 데도
큰 부담 없이 사용
할 수 있습니다.


AES 동작 🔥

위에서 설명한 것처럼,
AES는 데이터를 여러 번 섞고 바꾸는 작업을 반복합니다.
이 작업을 한번 빠르게 살펴보면서
AES의 동작을 알아보겠습니다.

1. 데이터 나누기

먼저, 암호화할 데이터를 128비트(16바이트) 블록 단위로 나눕니다.
예를 들어 "Hello, Backouts!!" 라는 문장을 암호화한다고 해봅시다.
이 문장은 17바이트이므로, 16바이트 블록과, 1바이트 블록,
총 2개의 블록으로 나뉘게 됩니다.

AES는 이 128비트 블록을 그냥 숫자의 덩어리로 다루지 않습니다.
대신, 16개의 바이트 단위로 나누고,
4 x 4 형태의 표(행렬)로 배치합니다.

이런 표를 State(상태행렬)라고 부릅니다.

총 16칸,
각 칸마다 1바이트(1글자)
전체가 16바이트(128비트)

[H e l l]
[o ,   B]
[a c k o]
[u t s !]

※ 실제 AES 내부에서는 문자 자체가 아니라,
각 문자가 UTF-8(ASCII) 바이트 값으로 변환되어 저장됩니다.

2. SubBytes (값 바꾸기)

SubBytes는 각 칸의 값을
미리 정해진 표(S-Box)를 이용해
다른 값으로 바꾸는 작업
입니다.

예를 들어, '0x48'('H')라는 바이트가 표에서 '0x3A'로 매핑되어 있다면,
'0x48'는 '0x3A'로 바뀌게 됩니다.

이 작업은 모든 칸에 대해 동시에 이루어집니다.

이 과정은 비선형 연산으로,
암호화의 복잡성을 높여줍니다.
이걸 혼돈이라고 부릅니다.

3. ShiftRows (위치 섞기)

ShiftRows
행(row) 단위로 데이터의 위치를 미는 작업입니다.

  • 첫 번째 행: 그대로
  • 두 번째 행: 1칸 이동
  • 세 번째 행: 2칸 이동
  • 네 번째 행: 3칸 이동

각 칸의 값 자체는 변하지 않지만,
같은 열에 있던 값들이 서로 다른 열로 흩어지게 됩니다.

예시

ShiftRows 이전 상태행렬

[  a0   a1   a2   a3 ]
[  b0   b1   b2   b3 ]
[  c0   c1   c2   c3 ]
[  d0   d1   d2   d3 ]

ShiftRows 이후 상태행렬

[  a0   a1   a2   a3 ] - 그대로
[  b1   b2   b3   b0 ] - 1칸 이동
[  c2   c3   c0   c1 ] - 2칸 이동
[  d3   d0   d1   d2 ] - 3칸 이동

4. MixColumns (강하게 섞기)

MixColumns
열(column) 단위로 데이터를 섞는 작업입니다.

한 열에 들어있는 4바이트가 서로 영향을 주며 함께 변합니다.

예시

ShiftRows 이후
다음과 같은 한 열(column)이 있다고 가정합니다.

[  a0  ]
[  b1  ]
[  c2  ]
[  d3  ]

MixColumns 이후
열은 아래와 같이 변합니다.

[  a' ]
[  b' ]
[  c' ]
[  d' ]

간단히 말하면 a는
b와 c, d, 그리고,
AES가 정해둔 MixColumns 행렬의 영향을 받아
a'가 됩니다.

a' = (02·a) ⊕ (03·b) ⊕ (01·c) ⊕ (01·d)
b' = (01·a) ⊕ (02·b) ⊕ (03·c) ⊕ (01·d)
c' = (01·a) ⊕ (01·b) ⊕ (02·c) ⊕ (03·d)
d' = (03·a) ⊕ (01·b) ⊕ (01·c) ⊕ (02·d)

⊕ = XOR

AES 표준에 정의된 MixColumns 행렬
[ 02 03 01 01 ]
[ 01 02 03 01 ]
[ 01 01 02 03 ]
[ 03 01 01 02 ]

위 수식에서 보다싶이
각 출력 값은
같은 열에 있던 모든 값의 영향을 받기 때문에,
입력의 작은 변화가 열 전체로 빠르게 확산됩니다.

5. AddRoundKey

이제 드디어 키를 사용합니다.
여기서 State 행렬과 라운드 키를 XOR 하게 됩니다. AES는 실제 암호화 라운드 과정에서
오직 이 단계에서만 키를 사용하게
됩니다.

라운드 키란
암호화를 시작하기 전에 딱 1번 실행되는
키 스케쥴 과정에서
대칭키로 가져온 비밀키를 재료로 생성된 키입니다.

State(128비트)
⊕ RoundKey (128비트)

6. 반복

AES-128은 위의 2 ~ 5의 과정을 10번 반복합니다.

다만 추가할 점이 있다면
첫 번째 라운드를 하기 전에,
AddRoundKey과정을 한번 하고 시작한다는 점
과,

마지막 10번째 라운드에서는
MixColumns 과정이 빠진다는 점
이 있습니다.


AES 정리

오늘은 AES가 무엇인지,
왜 빠른지,
그리고 AES의 동작과정에 대해 알아봤습니다.

사실 지금까지 알아본 AES는
현재는 조금 다른 방식으로 사용되고 있습니다.

평문을 암호화하는데 쓰이지 않고,
평문을 암호화 하기 위한
키스트림을 생성
하는데 주로 쓰이고 있습니다.

이것에 대해서는 다음에 AES 모드 설명과 함께 하도록 하겠습니다.


후기

AES는 한동안 제 골머리를 앓게 하고 있습니다.
제가 수학과 친하지 않아서 그런것도 있고,
최근에 프로젝트 일정과 겹쳐서 그런것도 있지만,

가장 큰 문제는 제가 너무 완벽하게 글을 쓰고싶어한다는 점입니다.
그래서 오늘부터는 생각을 조금 달리해서
완벽하지 않고, 짧더라도 글을 올리는것을 더 중요시 하기로 했습니다.

오늘 이 글에 포함되지 못한 내용들이 정말 많습니다.
혼돈과 확산이 무엇인지,
왜 마지막에 MixColumns를 쓰지 않는지,
왜 처음에 AddRoundKey를 하는지 등 추가하지 못한 내용들은 다음에 다루도록 하겠습니다.