바이트·KB·MB · Base64 · 해시 vs 암호화
1024 vs 1000, 이미지를 텍스트로(Base64), 되돌릴 수 없음(해시) vs 되돌릴 수 있음(암호화).
"파일 업로드 크기 제한" 설정, "이미지 인라인" 선택, "비밀번호를 암호화로 저장"(잘못된 표현) 같은 혼동을 정리. 보안 기초의 전제.
단위 혼동 주의. IT 업계는 10진(1 KB = 1,000 B)과 2진(1 KiB = 1,024 B)을 섞어 쓴다. 디스크 제조사는 10진(그래서 '1TB 샀는데 931GB'), OS·RAM은 2진. 1 MB는 보통 10진, 1 MiB는 2진.
| 단위 | 10진 (K·M·G) | 2진 (Ki·Mi·Gi) |
|---|---|---|
| K | 1,000 | 1,024 |
| M | 1,000,000 | 1,048,576 |
| G | 10⁹ | 2³⁰ (≈1.07×10⁹) |
| 쓰는 곳 | 저장장치 광고, 네트워크 대역 | RAM, 파일 크기 (OS) |
Base64는 바이너리를 텍스트로. 이미지·PDF를 JSON·HTML에 직접 넣고 싶을 때 쓴다. 6비트를 한 글자에 매핑하므로 데이터 크기가 약 33% 증가. 암호화 아님 — 누구나 디코드 가능.
// 브라우저
const b64 = btoa("Hello"); // "SGVsbG8="
atob("SGVsbG8="); // "Hello"
// Node.js (바이너리 안전)
Buffer.from("Hello").toString("base64"); // "SGVsbG8="
Buffer.from("SGVsbG8=", "base64").toString(); // "Hello"
// 이미지 인라인 (data URL)
<img src="data:image/png;base64,iVBORw0KGgo..." />
// 작은 아이콘은 편하지만 큰 이미지는 33% 부풀어서 로딩 느려짐Base64는 "암호화"가 아니다. 데이터 운반 형식 변환일 뿐. 토큰·비밀번호를 Base64만 해서 보내는 건 전혀 안전하지 않다.
해시 ≠ 암호화 (바이브코더 단골 혼동). 해시는 되돌릴 수 없는 요약(지문). 암호화는 키로 되돌릴 수 있는 변환. 비밀번호는 해시로 저장, 메시지는 암호화로 전송.
| 구분 | 해시 (Hash) | 암호화 (Encryption) |
|---|---|---|
| 되돌리기 | 불가 (일방향) | 가능 (양방향, 키 필요) |
| 크기 | 고정 (예: SHA-256 = 32바이트) | 입력에 비례 |
| 예시 | bcrypt, SHA-256, MD5 | AES, RSA, ChaCha20 |
| 용도 | 비밀번호 저장, 무결성 검증, 파일 지문 | 비밀 데이터 전송, TLS |
| ❌ 잘못된 용도 | 비밀 데이터 전송 (복호화 불가) | 비밀번호 저장 (탈취 시 복호화) |
import crypto from "node:crypto";
// 해시 — 파일 무결성 체크 (같은 파일인지 확인)
const hash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
// 예: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
// 비밀번호는 SHA-256 말고 반드시 bcrypt/argon2 (ch24-2 참고)
// 이유: SHA는 빠른 해시라 레인보우 테이블·GPU로 뚫림
// 암호화 — 대칭 (AES)
const key = crypto.randomBytes(32); // 256비트
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const authTag = cipher.getAuthTag(); // 무결성까지 보장
// 복호화는 같은 key + iv + authTag로
// 키는 환경변수·KMS로 안전 보관Claude가 'password를 암호화해서 저장' 같은 코드를 만들면 의심. 비밀번호는 해시(bcrypt/argon2), 비밀 데이터(API 키·개인정보)는 암호화(AES-GCM).
Base64 인코딩된 문자열은 암호화되어 있어 안전하다.
비밀번호를 저장할 때 적합한 것은 해시인가, 암호화인가?
Base64로 인코딩하면 데이터 크기는 원본의 몇 % 수준이 되는가?