본문으로 건너뛰기
yutils

암호화는 어떻게 동작할까?

대칭 (AES) vs 비대칭 (RSA / ECC), RSA 가 파일 직접 암호화 안 하는 이유 (hybrid encryption), block cipher mode (ECB 함정 vs GCM), key derivation (PBKDF2 / Argon2), at-rest vs in-transit, never-roll-your-own-crypto 룰.

약 10분 읽기

모든 backend 가 매일 만나지만 정확한 의미를 모르는 영역. 대칭 vs 비대칭? AES vs RSA? "RSA 로 큰 파일 암호화" 가 안 되는 이유? 이 가이드는 cryptography 의 핵심 원시를 알고리즘 detail 없이 정리한다 — 알고리즘은 라이브러리에 맡기고, 우리는 언제 어떤 도구를 쓰는지 알아야.

대칭 vs 비대칭 — 한 줄 차이

Symmetric (대칭):
  encrypt(plaintext, KEY)   = ciphertext
  decrypt(ciphertext, KEY)  = plaintext
  → 같은 key 로 양방향

대표: AES, ChaCha20

장점: 빠름 (GB/s), 키 작음
단점: key 어떻게 전달? 둘이 같은 key 가져야 함

────────────────────────────────────

Asymmetric (비대칭):
  encrypt(plaintext, PUBLIC_KEY)    = ciphertext
  decrypt(ciphertext, PRIVATE_KEY)  = plaintext
  → 다른 key 로 양방향

대표: RSA, ECC (Elliptic Curve)

장점: key 전달 안전 (public 공개해도 OK)
단점: 느림 (MB/s), 키 큼 (RSA 2048 bit = 256 byte)
       작은 데이터 (~수백 byte) 만 encrypt 가능

왜 둘 다 필요한가 — Hybrid Encryption

"RSA 로 100 MB 파일 암호화" 가 안 되는 이유:
- RSA encrypt 의 input 크기 한도 = key 크기 - padding (예: 245 byte)
- 100 MB / 245 byte = 408K 번 호출 = 매우 느림 + 비효율

해결: hybrid encryption (TLS, GPG, age 모두 이 패턴)

1. random AES key (32 byte) 생성
2. 100 MB 파일 → AES 로 encrypt (빠름)
3. 그 AES key 자체를 → RSA public key 로 encrypt (작음, OK)
4. encrypted file + encrypted AES key 같이 전송

수신자:
1. RSA private key 로 AES key decrypt
2. AES key 로 파일 decrypt

→ 두 방식의 좋은 점만 — AES 의 속도 + RSA 의 key exchange 안전.

Block Cipher Modes — 같은 알고리즘 다른 결과

AES 는 16 byte block 단위. 큰 데이터는 블록을 어떻게 chain 하느냐로 결과 다름.

ECB — 절대 쓰지 마라

ECB (Electronic Codebook):
  각 블록을 독립적으로 encrypt

블록 1: AES(KEY, block1) = X
블록 2: AES(KEY, block2) = Y
...

문제: 같은 plaintext block → 같은 ciphertext block
→ 패턴이 보임 (특히 이미지)

유명한 예: ECB 로 암호화한 Tux Linux 로고 — 원본 모양이 그대로 보임.
"penguin" 이미지 검색하면 바로 나옴.

CBC, CTR, GCM — 표준 modes

Mode특징사용 권장
ECB독립 block, 패턴 노출❌ 절대 X
CBC이전 block 과 XOR, IV 필요⚠ legacy (padding oracle 공격 위험)
CTRcounter 와 XOR (stream-like)✓ 빠름, 병렬 가능
GCMCTR + 무결성 검증 (authentication tag)✓✓ 추천 (encrypt + authenticate 동시)
ChaCha20-Poly1305대안 (mobile / CPU 약한 환경)✓✓ 추천

modern 표준 — AES-GCM 또는 ChaCha20-Poly1305. 둘 다 AEAD (Authenticated Encryption with Associated Data) — encrypt + integrity 동시.

Key Derivation — password → key

사용자 password "hunter2" 로 AES 암호화 직접 X — 너무 짧고 entropy 부족.
→ KDF (Key Derivation Function) 로 password → 32 byte AES key 변환.

PBKDF2 (2000):
  output = PBKDF2(password, salt, iterations=600_000, sha256, 32 byte)
  - iteration 많을수록 brute-force 비쌈
  - salt: 같은 password 가 다른 key 되도록 random
  - GPU/ASIC 에 비교적 취약

Argon2 (2015, modern 권장):
  output = Argon2id(password, salt, time=3, memory=64MB, parallelism=4)
  - GPU/ASIC 에 강함 (memory-hard)
  - bcrypt/scrypt 의 후속
  - 새 application 의 표준

scrypt (2009):
  비슷한 memory-hard. Argon2 이전의 권장.

bcrypt (1999):
  password hashing 표준 (encryption 의 KDF 아니지만 password storage 에).

At-Rest vs In-Transit

At-Rest: 저장된 데이터 (DB, 파일, backup) 의 암호화
  - cloud DB 의 default encryption (AWS RDS, GCP Cloud SQL 등)
  - 디스크 자체 암호화 (LUKS, BitLocker)
  - file-level 또는 application-level 암호화
  - key 는 KMS / Vault 에 (envelope encryption)

In-Transit: 전송 중 데이터
  - TLS (HTTPS, SMTPS, IMAPS, DB connection)
  - 서비스 간 mTLS
  - VPN, SSH

→ 둘 다 필요. at-rest 만 하고 in-transit 안 하면 → 네트워크 sniffing 가능.
→ in-transit 만 하면 → 디스크 leak 시 전부 노출.

Never Roll Your Own Crypto

흔한 위반:
- "AES 직접 구현했어요" — side-channel 공격 (timing, power) 회피 어려움
- "XOR 로 간단 암호화" — 즉시 깨짐 (frequency analysis)
- 자체 KDF — iteration 부족, salt 없음
- 자체 random number generator — Math.random() 은 cryptographically secure X

규칙:
- 알고리즘은 라이브러리 (libsodium, OpenSSL, Web Crypto API)
- 모드는 표준 (AES-GCM, ChaCha20-Poly1305)
- random 은 crypto.getRandomValues / crypto.randomBytes
- key derivation 은 Argon2 또는 PBKDF2

이유:
- 알고리즘은 수학자 / 암호학자가 검증 후 표준화
- side-channel 공격 방어는 implementation detail
- 자체 구현은 거의 항상 fault — 25년 전 Schneier 의 명언

관련 도구

  • SHA 해시 — SHA-256 등 hash (encryption 과 다른 영역 — 일방향)
  • Bcrypt 해시 — password hashing (KDF 의 일종)
  • HMAC 생성기 — message authentication (integrity, not encryption)

흔한 함정

  • ECB 사용 — 위 참조. 어떤 modern application 도 ECB 안 됨.
  • 같은 IV / nonce 재사용 — GCM 의 보안 깨짐. 매 encryption 마다 unique random IV.
  • hash = encryption 혼동 — SHA-256 은 일방향 (decrypt 불가능). encryption 은 양방향. password 저장은 hash, 데이터 보호는 encryption.
  • Math.random() 으로 key 생성 — predictable. 반드시 crypto.getRandomValues / SecureRandom.
  • encryption only, no integrity — encrypt 한 데이터를 attacker 가 수정 가능 (bit flip). GCM 같은 AEAD 사용.

마무리

Encryption 의 본질 — 알고리즘 detail 은 라이브러리, 우리의 책임은 올바른 도구 선택. 대칭 vs 비대칭 (또는 hybrid), AEAD mode (GCM/ChaCha20), 적절한 KDF (Argon2/PBKDF2).

실용 — modern application 의 기본: AES-256-GCM (또는 ChaCha20-Poly1305) + Argon2id (password KDF) + TLS 1.3 (in-transit) + cloud KMS (key management). 자체 구현 0.

가이드 목록으로