← Posts

Cryptography · AES · Symmetric

대칭키 암호 - 열쇠 하나로 잠그고 연다

AES는 블록 단위로 감춘다. 같은 블록이 같게 나오면 새는 이유, 열쇠 길이가 안전을 정하는 법, 그리고 남는 단 하나의 문제 - 열쇠를 어떻게 건네나.

목차
  1. 같은 열쇠로 잠그고 연다
  2. 블록 단위로 자른다
  3. 같은 블록이 같게 나오면 샌다
  4. 그래서 앞 블록을 섞는다
  5. 열쇠는 얼마나 길어야 하나
  6. 진짜 문제는 열쇠를 어떻게 건네나
  7. 실무에서: 모드를 직접 고르지 않는다
  8. 정리

집 열쇠를 떠올리면 된다. 잠글 때 쓴 열쇠로 연다. 대칭키 암호가 그렇다 - 단순한 만큼 빠르고, 그래서 실제 데이터는 대부분 이걸로 감춘다.

같은 열쇠로 잠그고 연다

대칭키는 암호화와 복호화에 같은 열쇠를 쓴다. 대표가 AES다.

plaintext
평문  --AES 암호화(열쇠 K)-->  암호문  --AES 복호화(열쇠 K)-->  평문

열쇠를 가진 두 사람만 서로의 메시지를 읽는다. 원리가 하나뿐이라 공개키보다 수백~수천 배 빠르다 - 큰 파일, 통신 본문, 디스크 전체 암호화는 거의 다 대칭키다. 문제는 뒤에서 나온다. 이 “같은 열쇠”를 상대에게 어떻게 건네느냐다.

블록 단위로 자른다

AES는 데이터를 통째로 다루지 않는다. 고정 크기(16바이트) 블록으로 잘라 한 덩어리씩 암호화한다(그래서 “블록 암호”다).

plaintext
평문:  [ 16B ][ 16B ][ 16B ][ 나머지 ]
         ↓      ↓      ↓        ↓ (패딩으로 16B 채움)
암호문:[ 16B ][ 16B ][ 16B ][ 16B ]

딱 안 떨어지는 마지막 조각은 패딩으로 채워 16바이트를 맞춘다. 여기까진 단순하다. 그런데 블록을 각각 따로 암호화하면 곧바로 새는 구멍이 생긴다.

같은 블록이 같게 나오면 샌다

블록마다 같은 열쇠로 독립 암호화하면(이 방식을 ECB라 한다), 같은 평문 블록은 같은 암호문 블록이 된다. 열쇠를 몰라도 패턴이 그대로 비친다.

유명한 예가 있다. 이 방식으로 이미지를 암호화하면 색이 넓게 반복되는 그림은 암호문에서도 윤곽이 그대로 보인다 - 같은 색 블록이 같은 암호 블록으로 나와서다. 내용을 못 읽어도 “무슨 그림인지”는 드러난다. 텍스트도 마찬가지다. 반복되는 헤더나 구조가 그대로 노출된다.

암호문이 무작위처럼 안 보이면 이미 실패다. 그래서 블록을 따로 굴리면 안 된다.

그래서 앞 블록을 섞는다

해법은 각 블록을 앞 블록의 결과와 섞고 나서 암호화하는 것이다(대표적으로 CBC 모드). 그러면 같은 평문이라도 앞이 다르면 암호문이 달라진다.

diagramdiagram

맨 앞엔 섞을 이전 블록이 없으니 **IV(초기화 벡터)**라는 무작위 시작값을 넣는다. IV가 매번 다르면 같은 평문을 같은 열쇠로 암호화해도 결과가 매번 달라진다 - 이게 목표다. IV는 비밀이 아니어도 되지만 매번 새로 무작위여야 한다. 재사용하면 다시 패턴이 샌다.

열쇠는 얼마나 길어야 하나

열쇠를 모르면 남는 공격은 다 넣어보는 것(무차별 대입)뿐이다. 그래서 안전은 곧 열쇠 길이다. AES 열쇠는 128비트 또는 256비트다.

  • 128비트면 가능한 열쇠가 2^128개다. 세상의 모든 컴퓨터를 모아도 우주 나이 동안 세도 다 못 넣어본다.
  • 256비트는 그보다 2^128배 더 많다.

여기서 초중급이 흔히 헷갈리는 것 - 비밀번호가 곧 열쇠가 아니다. 사람이 외우는 비밀번호는 128비트 무작위가 아니라 훨씬 약하다. 그래서 비밀번호로 암호화할 땐 그걸 그대로 열쇠로 쓰지 않고 늘려서(키 파생) 쓴다. 이 “약한 비밀번호를 어떻게 다루나”는 비밀번호 저장 글에서 정면으로 다룬다.

진짜 문제는 열쇠를 어떻게 건네나

여기까지 오면 대칭키는 빠르고 튼튼하다. 그런데 결정적인 구멍이 하나 남는다. 두 사람이 같은 열쇠를 나눠 가져야 하는데, 그 열쇠 자체를 어떻게 건네나.

plaintext
철수 --- (이 열쇠 K를 영희에게 보내야 한다) ---> 영희
              ↑ 그런데 이 경로가 안전하면
                애초에 암호가 왜 필요했나?

이게 키 분배 문제다. 열쇠를 안전하게 건넬 통로가 있었다면 그 통로로 그냥 메시지를 보냈으면 된다. 게다가 통신 상대가 늘면 열쇠 쌍도 폭발한다 - n명이 서로 통신하려면 열쇠가 대략 n²/2개 필요하다.

대칭키만으로는 이걸 못 푼다. 다음 글의 공개키가 바로 이 문제를 풀려고 나왔다.

실무에서: 모드를 직접 고르지 않는다

지금은 CBC보다 AES-GCM을 쓴다. GCM은 감추기(기밀성)에 더해 위조 감지(무결성)까지 한 번에 한다 - 암호문이 중간에 바뀌면 복호화가 실패한다(이 “인증된 암호화”의 무결성 쪽은 해시와 HMAC 글과 이어진다). 그래서 실무의 선택은 대개 이렇게 좁다.

  • 모드는 GCM, 열쇠는 256비트. ECB는 쓰지 않는다.
  • IV/논스는 매번 새 무작위. 라이브러리에 맡기고 재사용하지 않는다.
  • 열쇠는 코드·git에 안 박는다. 키 관리 서비스(KMS)나 시크릿 저장소에 둔다.

원리를 배웠으니 이 한 줄들이 왜 그런지 보인다 - IV 재사용 금지도, ECB 금지도, 전부 “암호문이 무작위처럼 보여야 한다”는 한 원칙에서 나온다.

정리

  • 대칭키는 같은 열쇠로 잠그고 연다. 빠르고, 그래서 실제 데이터 감추기는 대부분 이걸(AES) 쓴다.
  • AES는 블록 단위로 감춘다. 블록을 따로 굴리면(ECB) 패턴이 새므로, IV를 섞어 매번 다르게(CBC·GCM 등) 암호문이 무작위처럼 나오게 한다.
  • 안전은 열쇠 길이가 정한다(128/256비트). 단 사람 비밀번호는 열쇠만큼 강하지 않다.
  • 남는 단 하나의 구멍이 키 분배 - 같은 열쇠를 어떻게 건네나. 이걸 공개키가 푼다.

다음 글은 잠그는 열쇠와 여는 열쇠를 둘로 나눈 공개키 암호, 그리고 대칭키와 합쳐 쓰는 하이브리드를 본다.

관련 글