[데이터 변환 이해 1편] 인코딩 · 암호화 · 해시 — 세 개념의 차이
왜 이 셋이 헷갈리는가?
세 개념은 모두 “데이터를 다른 형태로 바꾼다”는 점에서 겉보기에 비슷하다.
하지만 목적, 가역성, 키 필요 여부가 근본적으로 다르다.
전체 지도
데이터 변환
│
├── 인코딩 (Encoding)
│ 목적: 형식 변환 (전송·저장을 위한 표현 방식 변경)
│ 가역성: ✅ 복원 가능
│ 키: 없음
│ 보안: ❌ 보안 수단이 아님
│ 예: Base64, UTF-8, URL 인코딩
│
├── 암호화 (Encryption)
│ 목적: 기밀성 보호 (허가된 사람만 복원 가능)
│ 가역성: ✅ 복원 가능 (키 있으면)
│ 키: ✅ 필요
│ 보안: ✅ 보안 수단
│ 예: AES, RSA
│
└── 해시 (Hash) ← 암호화와 다름. 별도 범주
목적: 무결성 검증 · 인증
가역성: ❌ 복원 불가 (단방향)
키: 없음 (bcrypt는 salt 사용)
보안: ✅ 보안 수단 (목적이 다름)
예: SHA-256, bcrypt, MD5
핵심 차이 한 눈에
| 항목 | 인코딩 | 암호화 | 해시 |
|---|---|---|---|
| 원래 값 복원 | ✅ 가능 | ✅ 가능 (키 필요) | ❌ 불가 |
| 키 필요 | 없음 | 있음 | 없음 |
| 목적 | 형식 변환 | 기밀 보호 | 무결성·인증 |
| 보안 수단 | ❌ | ✅ | ✅ (다른 방식으로) |
해시를 왜 따로 분리하는가
흔히 “해시 암호화”라는 표현을 쓰지만, 이는 잘못된 표현이다.
암호화는 복원을 전제로 한다.
평문 → [암호화, 키 사용] → 암호문 → [복호화, 키 사용] → 평문
해시는 복원이 원천적으로 불가능하다.
평문 → [해시 함수] → 해시값
↑
여기서 끝. 원래 값으로 돌아갈 수 없음
같은 입력은 항상 같은 해시값을 만들지만,
해시값으로 원래 입력을 알아낼 수 없다.
해시가 쓰이는 이유
복원이 불가능하기 때문에 오히려 유용한 경우가 있다.
비밀번호 저장
사용자: "password123" 입력
DB 저장: "$2b$12$eImiTXuWVxfM37uY4JANjQ..." (bcrypt 해시)
→ 해킹당해도 원래 비밀번호를 알 수 없음
→ 로그인 시 입력값을 같은 방식으로 해시해서 비교
파일 무결성 검증
다운로드 파일의 SHA-256을 공식 값과 비교
→ 파일이 변조됐는지 확인
→ 원본 파일 내용이 아닌 "동일성"만 검증
이처럼 해시는 “복원 필요 없이 동일성·무결성을 증명” 할 때 쓴다.
목적과 동작 원리가 암호화와 다르기 때문에 별도 범주로 분리한다.
실무 선택 기준
데이터를 다른 형식으로 바꿔야 한다
└→ 원래 값이 필요한가?
│
YES → 비밀을 보호해야 하는가?
│ │
│ YES → 암호화 (AES, RSA)
│ NO → 인코딩 (Base64, UTF-8, URL)
│
NO → 해시 (SHA-256, bcrypt)
실수 유형
❌ 잘못된 사용
- Base64로 비밀번호 "인코딩" → 바로 복원 가능, 보안 아님
- MD5로 비밀번호 저장 → 레인보우 테이블로 역추적 가능
- 암호화로 비밀번호 저장 → 키가 유출되면 전부 복원 가능
✅ 올바른 사용
- 비밀번호 → bcrypt 해시
- API 키 전송 → AES 암호화 또는 TLS
- 이미지 첨부 이메일 → Base64 인코딩
- URL 파라미터 특수문자 → URL 인코딩
이 시리즈에서 다루는 것
1편 (이 글) 인코딩 · 암호화 · 해시 — 세 개념의 차이
↓
2편 [[data-encoding-types|인코딩 유형 — 문자 인코딩, Base64, URL 인코딩]]
↓
3편 [[data-encryption-types|암호화 유형 — 대칭키, 비대칭키, 해시 함수]]