암호화 기법
- 3.1 암호화 도구
- 3.2 난수
- 3.3 메시지 인증 코드
- 3.4 대칭 암호화
- 3.5 대칭 암호화 사용
- 3.6 비대칭 암호화
- 3.7 디지털 서명
- 3.8 디지털 인증서
- 3.9 키 교환
- 3.10 암호화 사용
암호화는 직접 만들면 안 되고, 잘 골라서 잘 써야 해. 3장의 핵심은 이거야.
개발자가 암호학 박사가 될 필요는 없어. 근데 각 도구가 뭘 해주고 뭘 안 해주는지는 정확히 알아야 해. 도구상자를 열어보면 — 해시 함수는 데이터의 지문을 만들어서 무결성을 확인하는 용도(SHA-256, SHA-3), MAC은 해시에 비밀 키를 더해서 "누가 보냈는지"까지 확인하는 용도(HMAC-SHA256), 대칭 암호화는 같은 키로 암호화/복호화하는 빠른 방식(AES), 비대칭 암호화는 공개키/개인키 쌍으로 키 배포 문제를 해결하는 방식(RSA, ECC). 각각 용도가 다르니까 섞어 쓰면 안 돼.
실무에서 가장 중요한 건 구현 디테일이야. 난수부터 보면 — Math.random() 같은 일반 PRNG는 보안 목적으로 절대 쓰면 안 돼. 시드를 알면 출력을 예측할 수 있거든. Java면 SecureRandom, Python이면 secrets, Node.js면 crypto.randomBytes()를 써야 해. 대칭 암호화에서는 AES-GCM이 현재 표준인데, 암호화와 인증을 동시에 해줘서 변조 감지까지 가능해. 절대 ECB 모드 쓰지 말고(같은 평문이 같은 암호문을 만들어서 패턴이 드러나), IV/Nonce를 재사용하면 키가 복원될 수 있어. MAC 비교할 때는 == 대신 상수 시간 비교 함수를 써야 타이밍 공격을 막을 수 있어 — 응답 시간 차이로 올바른 MAC을 한 바이트씩 추측하는 공격이거든.
비대칭 암호화는 느리니까 실제로는 하이브리드 방식을 써. 비대칭으로 대칭 키를 안전하게 전달한 뒤, 이후 통신은 대칭으로 하는 거지 — TLS가 정확히 이렇게 동작해. 여기서 **순방향 비밀성(PFS)**이 중요한데, 세션마다 키 교환을 새로 하면 나중에 장기 키가 유출되어도 과거 통신을 복호화할 수 없어. TLS 1.3에서는 PFS가 필수야. 디지털 인증서는 공개키가 진짜 그 주체의 것인지 CA가 보증하는 구조고, Let's Encrypt 덕분에 HTTPS 안 쓸 이유가 사라졌지.
마지막으로 두 가지만 기억해. 첫째, 검증된 라이브러리의 고수준 API를 써라. libsodium, Tink 같은 거. 저수준 API는 실수할 여지가 너무 많아. 둘째, **암호화 민첩성(Crypto Agility)**을 확보해라. 지금 쓰는 알고리즘이 언젠가 깨질 수 있거든. 코드 전체에 특정 알고리즘을 하드코딩하면, 교체할 때 대규모 수정이 필요해져. 양자 컴퓨팅 시대에 RSA, ECC가 깨질 수 있다는 건 먼 미래 얘기 같지만, NIST가 이미 포스트 양자 표준을 선정한 걸 보면 — 대비는 지금부터 해야 해.
정리
3장 읽고 기억할 거 세 가지:
- 도구마다 용도가 달라. 해시는 무결성, MAC은 무결성+인증, 대칭 암호화는 기밀성, 비대칭은 키 교환과 서명. 섞어 쓰면 안 돼.
- 구현 디테일이 전체 보안을 결정해. CSPRNG 쓰기, IV/Nonce 재사용 금지, 상수 시간 비교 — 이런 사소해 보이는 것들이 암호화를 살리거나 죽여.
- 직접 만들지 말고, 교체 가능하게 설계해. 검증된 라이브러리를 쓰되, 알고리즘을 바꿀 수 있도록 암호화 민첩성을 확보해둬야 해.