에듀테크 프로젝트 대시보드
블록 암호 운용 모드
AES 같은 블록 암호는 한 번에 고정 크기(예: 16바이트) 블록 하나만 암호화한다. 데이터가 그보다 길면 여러 블록으로 잘라 운용 모드(mode of operation) 규칙에 따라 이어 붙인다. 같은 키·같은 알고리즘이라도 모드 선택 하나로 안전성이 크게 갈린다. 아래 "ECB 펭귄" 데모로 그 차이를 눈으로 확인해 보자.
그림을 8×8 픽셀 블록으로 나눠 각 블록을 "암호화"한다. ECB는 블록마다 독립적으로 암호화하므로 같은 평문 블록 → 항상 같은 암호문 블록이 되어, 큰 색 덩어리·윤곽선 같은 패턴이 암호문에도 남는다. CBC는 각 블록을 암호화 전에 직전 암호문 블록과 XOR해 연쇄시키므로 같은 평문이라도 매번 달라져 노이즈처럼 보인다.
※ 실제 AES가 아니라 원리를 보여 주기 위한 교육용 시뮬레이션이다(블록 내용을 해시해 색으로 매핑). 핵심 성질 — "ECB는 반복 블록이 반복 패턴으로 남는다" — 은 실제 AES-ECB에서도 똑같이 나타난다.
CBC의 첫 블록은 XOR할 "직전 암호문"이 없다. 그래서 IV(Initialization Vector, 초기화 벡터)라는 랜덤한 블록을 하나 만들어 대신 XOR한다. IV 규칙:
같은 평문·같은 키라도 IV가 다르면 암호문 전체가 달라진다. 그래서 "이 메시지 = 저번 그 메시지"임을 공격자가 못 알아챈다.
IV는 암호문 맨 앞에 그냥 붙여 보내도 안전하다. 복호화하려면 필요하기 때문. 단 예측 가능하면 안 된다.
ECB와 비슷한 약점이 부활한다 — 같은 시작을 가진 두 메시지는 앞부분 암호문이 똑같이 나온다.
CTR·GCM 같은 스트림형 모드에서 nonce를 재사용하면 키스트림이 겹쳐 XOR 한 방에 평문이 드러난다. 치명적.
직접 XOR 연쇄를 짤 일은 거의 없다. 라이브러리에 모드를 지정하고, 인증 암호화(AEAD) 모드를 고르는 게 요즘 권장이다.
# pip install cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM import os key = AESGCM.generate_key(bit_length=256) nonce = os.urandom(12) # 매번 새로! 재사용 금지 aead = AESGCM(key) ct = aead.encrypt(nonce, b"secret message", None) pt = aead.decrypt(nonce, ct, None) # 변조되면 예외 발생 → 무결성까지 보장 # CBC를 꼭 써야 한다면 (레거시 호환 등) from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes iv = os.urandom(16) enc = Cipher(algorithms.AES(key), modes.CBC(iv)).encryptor() # 평문은 16바이트 배수로 패딩(PKCS7) 필요, 그리고 별도 MAC로 무결성 확인해야 함
| 모드 | 연쇄 | 병렬 | 패딩 | 무결성 | 평가 |
|---|---|---|---|---|---|
| ECB | 없음 | 암·복호 모두 | 필요 | 없음 | ❌ 쓰지 말 것 |
| CBC | 암호문 체인 | 복호화만 | 필요 | 없음(별도 MAC) | ⚠️ 레거시 |
| CTR | 카운터 스트림 | 암·복호 모두 | 불필요 | 없음(별도 MAC) | ⚠️ nonce 관리 주의 |
| GCM | CTR + 인증 | 암·복호 모두 | 불필요 | ✅ 내장(AEAD) | ✅ 기본 선택 |
정리 — ① 블록 암호는 그 자체론 "16바이트 한 조각"만 처리한다. ② 긴 데이터를 어떻게 잇느냐가 모드다. ③ ECB는 패턴을 노출해 실패했고(펭귄!), CBC는 IV와 체이닝으로 이를 가린다. ④ 하지만 CBC도 변조 탐지는 못 하므로, 오늘날은 암호화와 인증을 한 번에 하는 AES-GCM 같은 AEAD 모드가 표준이다.