목차
“암호화했다”는 말은 자주 세 가지 다른 일을 뭉뚱그린다. 그 셋을 먼저 갈라놓는다.
암호는 세 가지를 지킨다
편지 한 통을 남에게 맡겨 보낸다고 하자. 걱정거리는 셋이다.
- 엿보기 - 중간에 누가 뜯어 읽는다. → 못 읽게 하고 싶다(기밀성).
- 위조 - 중간에 누가 내용을 고친다. → 고쳐졌으면 알아채고 싶다(무결성).
- 사칭 - 보낸 사람이 내가 아니다. → 진짜 보낸 사람을 확인하고 싶다(신원).
암호 기술은 이 셋을 각각 다른 도구로 푼다. 뒤에 나올 대칭키·공개키는 기밀성을, 해시·HMAC은 무결성을, 서명·인증서는 신원을 맡는다. 그래서 “암호화 = 감추기”라고만 알면 절반만 아는 것이다. 감추는 건 셋 중 하나다.
인코딩은 감추는 게 아니다
가장 흔한 오해부터 걷어낸다. Base64로 바꾼 문자열은 암호처럼 생겼지만 아무나 되돌린다.
Hello → SGVsbG8= (Base64 인코딩)
SGVsbG8= → Hello (열쇠 없이, 누구나)인코딩은 모양을 바꿀 뿐 열쇠가 없다. 바이너리를 텍스트로 실어 나르려고(이메일·URL·JSON) 쓰는 것이지 감추려고 쓰는 게 아니다. JWT의 가운데 조각이 Base64라 그 안의 이메일이 그냥 읽히는 것도 같은 이유다 - 인코딩은 보안이 아니다.
해싱은 되돌릴 수 없다
해싱은 반대쪽 극단이다. 임의 길이의 입력을 고정 길이의 지문으로 뭉갠다. 그리고 되돌리는 열쇠가 아예 없다 - 설계가 단방향이다.
"password123" → ef92b778bafe771e89245b89ecbc08a4... (SHA-256)
"password124" → 5e884898da28047151d0e56f8dc62927... (한 글자 바꿨는데 완전히 다르다)같은 입력은 늘 같은 지문을 낸다. 그래서 “내용이 바뀌었나”를 지문끼리 비교해 알 수 있다(무결성). 하지만 지문에서 원본을 복원할 수는 없다. 이게 암호화가 아니라는 게 핵심이다 - 감춘 게 아니라 한 방향으로 뭉갠 것이다.
암호화는 열쇠가 있으면 되돌린다
암호화는 그 가운데다. 원본을 알아볼 수 없게 바꾸되, 맞는 열쇠가 있으면 되돌린다.
"Hello" --암호화(열쇠)--> 8f3a9c... --복호화(열쇠)--> "Hello"
열쇠 없으면 못 돌린다셋을 “되돌릴 수 있느냐”로 세워보면 한눈에 갈린다.
| 되돌리기 | 무엇으로 | 쓰는 이유 | |
|---|---|---|---|
| 인코딩 | 누구나 | 열쇠 없음 | 실어 나르기 |
| 암호화 | 열쇠 있으면 | 열쇠 | 감추기(기밀성) |
| 해싱 | 아무도 못 함 | 단방향 | 지문 맞추기(무결성) |
이 표 하나가 이 시리즈의 뼈대다. 감추려면 암호화, 바뀌었나 보려면 해시, 실어 나르려면 인코딩. 셋을 섞어 쓰면 사고가 난다 - 비밀번호를 “인코딩”해 저장한다든가.
열쇠가 하나냐 둘이냐
감추는 쪽(암호화)은 다시 두 갈래다. 열쇠가 하나면 대칭키, 둘이면 공개키(비대칭).
대칭키는 잠글 때와 열 때 같은 열쇠를 쓴다(집 열쇠처럼). 공개키는 잠그는 열쇠와 여는 열쇠가 다르다 - 잠그는 쪽은 공개해도 되고, 여는 쪽만 나만 갖는다. 이 “둘로 나뉜다”가 왜 필요한지는 공개키 글에서 본다.
왜 하나로 안 되나
그럼 편한 걸로 하나만 쓰면 될 텐데, 둘 다 쓴다. 각자 못 하는 게 있어서다.
- 대칭키는 빠르다. 대신 열쇠를 상대에게 어떻게 건네나 - 열쇠 자체가 도청되면 끝이다(키 분배 문제).
- 공개키는 그 분배 문제를 푼다(여는 열쇠를 안 건네도 되니까). 대신 느리다 - 큰 데이터를 통째로 공개키로 암호화하면 감당이 안 된다.
그래서 실제 시스템은 공개키로 대칭키만 몰래 건네고, 본문은 빠른 대칭키로 감춘다. 이 조합이 공개키 글에서 볼 하이브리드고, HTTPS가 매 접속에 하는 일이다.
암호가 안 지키는 것
암호를 걸어도 남는 게 있다. 초중급에서 놓치기 쉬운 대목이다.
- 누가 누구와 통신하는지(메타데이터)는 대개 안 감춰진다. 내용은 못 봐도 “이 사람이 저 은행 서버와 오래 통신했다”는 보인다.
- 재전송은 암호만으로 안 막는다. 도청자가 뜻을 몰라도 “그 요청 그대로 한 번 더” 흘려보내면 통할 수 있다(그래서 JWT에 만료가, 결제엔 멱등키가 붙는다).
- 가용성은 암호의 소관이 아니다. 서버를 마비시키는 공격은 암호가 막아주지 않는다.
암호는 “엿보기·위조·사칭”을 막지, “통신했다는 사실”이나 “서비스가 살아 있음”까지 지키진 않는다.
실무에서: 직접 만들지 않는다
이 시리즈는 원리를 이해하려고 알고리즘 속을 들여다보지만, 실무의 첫 규칙은 반대다. 암호는 직접 구현하지 않는다. 라이브러리·표준 프로토콜을 쓴다.
이유는 원리를 알수록 분명해진다 - 암호는 “맞게 작동하는 것”과 “안전한 것”이 다르다. 열쇠를 잘못 재사용하거나, 비교를 한 글자씩 하다 시간차로 새거나(타이밍 공격), 난수가 안 무작위면 알고리즘이 옳아도 뚫린다. 이런 함정은 이미 검증된 구현이 피해준다. 원리를 배우는 목적은 직접 짜려는 게 아니라, 남이 짠 걸 옳게 고르고 쓰려는 것이다 - 대칭이냐 공개키냐, 해시로 될 일에 암호화를 쓰고 있진 않은지, 비밀번호를 감추려 한 건지 지문만 남기려 한 건지.
정리
- 암호는 세 가지를 지킨다 - 기밀성(엿보기)·무결성(위조)·신원(사칭). 감추기는 그중 하나다.
- 되돌리기로 셋이 갈린다. 인코딩=누구나, 암호화=열쇠 있으면, 해싱=아무도 못 함. 섞어 쓰면 사고 난다.
- 감추기(암호화)는 열쇠가 하나면 대칭, 둘이면 공개키. 대칭은 빠르나 키 분배가, 공개키는 분배를 풀지만 속도가 문제라 - 실무는 둘을 합쳐 쓴다.
- 암호는 메타데이터·재전송·가용성까지 지키진 않는다. 그리고 직접 만들지 않는다.
다음 글은 셋 중 가장 오래된 것, 열쇠 하나로 잠그고 여는 대칭키 암호부터 본다.