알아두면 좋은 내용
Base64 인코딩 원리
Base64는 바이너리 데이터를 64개의 ASCII 문자(A-Z, a-z, 0-9, +, /)로 표현하는 인코딩 방식입니다. 텍스트 기반 시스템에서 이진 데이터를 안전하게 전송하기 위해 1987년 RFC 989(PEM)에서 처음 등장했고, 1993년 RFC 1421을 거쳐 현재는 RFC 4648 표준입니다.
입력이 3바이트로 나누어떨어지지 않으면 마지막 묶음을 0비트로 채워 인코딩하고, 모자란 자리를 =로 표시합니다. 1바이트가 남으면 ==, 2바이트가 남으면 = 하나가 붙어 출력 길이는 항상 4 × ⌈바이트 수 ÷ 3⌉입니다. 한글 한 글자는 UTF-8로 3바이트라 패딩 없이 4문자가 되고, 글자 수가 아니라 바이트 수가 길이를 정한다는 점이 중요합니다. 위 인코더에 같은 글자를 넣으면 표와 같은 값이 나오고, URL-safe 모드로 바꾸면 마지막 열처럼 =가 빠집니다.
| 입력 | UTF-8 바이트 | 표준 Base64 | 패딩 | URL-safe (패딩 제거) |
|---|---|---|---|---|
| A | 1바이트 | QQ== | 2개 | |
| AB | 2바이트 | QUI= | 1개 | QUI |
| ABC | 3바이트 | QUJD | 없음 | QUJD |
| Hi | 2바이트 | SGk= | 1개 | SGk |
| 한 | 3바이트 | 7ZWc | 없음 | 7ZWc |
| 한글 | 6바이트 | 7ZWc6riA | 없음 | 7ZWc6riA |
Base64 주요 사용 사례
이메일 첨부파일
MIME 표준에서 이미지·문서를 7-bit ASCII로 안전하게 전송
JWT 토큰
JSON Web Token의 헤더·페이로드를 URL-safe Base64로 인코딩
이미지 Data URI
HTML/CSS에 이미지를 직접 임베드 (data:image/png;base64,...)
HTTP Basic 인증
Authorization 헤더에 user:password를 Base64로 전송
PDF 임베드
API 응답에 PDF 바이너리를 텍스트로 포함
PEM 인증서
X.509 인증서·SSH 키를 텍스트 파일로 저장
표준 Base64 vs URL-safe Base64
| 항목 | 표준 Base64 | URL-safe (RFC 4648 §5) |
|---|---|---|
| 치환 | +, /, = | -, _, (없음) |
| 패딩 (=) | 항상 포함 | 생략 가능 |
| URL/파일명 | 퍼센트 인코딩 필요 | 그대로 사용 |
| 주요 사용처 | 이메일·일반 | JWT·OAuth·URL |
SGVsbG8/V29ybGQ+ → URL-safe SGVsbG8_V29ybGQ-. 표준 Base64를 쿼리 문자열에 그대로 넣으면 +가 공백으로 해석돼 디코딩이 깨지는 일이 흔합니다. URL에 넣을 값이라면 처음부터 URL-safe로 인코딩하거나, 표준 값을 퍼센트 인코딩(%2B·%2F·%3D)하세요.환경별 Base64 코드 — 한글 처리 3종 비교
브라우저의 btoa()는 Latin-1(0~255) 범위 문자만 받으므로 한글을 직접 넣으면 InvalidCharacterError가 발생합니다. 해결의 핵심은 어떤 환경이든 문자열을 UTF-8 바이트로 먼저 변환하는 것이며, 아래 세 패턴 모두 "한글"을 동일한 결과 7ZWc6riA로 인코딩합니다.
| 항목 | ① 레거시 패턴 | ② TextEncoder | ③ Node Buffer |
|---|---|---|---|
| 한글 처리 | ✓ 가능 | ✓ 가능 | ✓ 가능 |
| 표준 상태 | unescape 폐기(deprecated) | 웹 표준 권장 | Node 내장 (브라우저 불가) |
| URL-safe | 수동 치환 필요 | 수동 치환 필요 | 'base64url' 지정 |
| 주의점 | 한 줄로 간편·구형 코드에 잔존 | 대용량은 스프레드 대신 청크 분할 | 디코딩 시 인코딩 문자열 명시 |
unescape가 폐기 API라 신규 코드에는 권장되지 않지만, 기존 코드 해석을 위해 알아둘 가치가 있습니다. ②에서 수십 KB 이상 대용량을 다룰 땐 String.fromCharCode(...bytes)의 인수 개수 제한 때문에 바이트 배열을 청크로 나눠 처리해야 합니다.JWT(JSON Web Token) 구조
HEADER
알고리즘(alg)·토큰 타입(typ). 예: HS256, RS256
PAYLOAD (Claims)
사용자 정보·만료 시간(exp)·발급(iat)·발급자(iss)·대상(aud)
SIGNATURE
HEADER.PAYLOAD를 비밀키로 서명. 위변조 검증용.
JWT exp·iat 읽는 법 — epoch 초 → 한국 시간
JWT 표준(RFC 7519)은 exp(만료)·iat(발급)·nbf(활성 시작)를 1970-01-01 00:00 UTC부터 경과한 초 단위 숫자(NumericDate)로 정의합니다. JavaScript의 Date는 밀리초 기준이므로 1000을 곱한 뒤 변환하고, 한국 시간(KST)은 UTC보다 9시간 빠릅니다.
위 예시 토큰은 2026-01-01 08:00 KST에 발급(iat)되어 09:00 KST에 만료(exp)되는 유효기간 1시간짜리입니다 (1767225600 − 1767222000 = 3,600초). 본 도구의 JWT 모드에 토큰을 붙여 넣으면 이 변환을 자동으로 수행합니다.
new Date(1767225600)을 호출하면 1970-01-21로 계산되어 "항상 만료"로 오판합니다. 반대로 서버가 밀리초 값을 exp에 넣으면 수만 년 뒤 만료로 인식돼 사실상 무기한 토큰이 됩니다. exp가 10자리(초, 2001~2286년 구간)인지 13자리(밀리초)인지부터 확인하세요.이미지 Data URI 활용
✅ 적합한 경우
- 작은 아이콘 (< 5KB)
- CSS 배경 이미지 단일 파일
- 오프라인 HTML 이메일 템플릿
- 캐시 분리가 불필요한 경우
❌ 부적합한 경우
- 큰 이미지 (> 50KB)
- 여러 페이지에서 재사용
- 브라우저 캐싱이 중요할 때
- 이미지 최적화·CDN 활용 필요
인코딩 방식 비교 ("Hi" 기준)
| 인코딩 | 결과 | 주요 용도 |
|---|---|---|
| Base64 | SGk= | 이메일·일반 바이너리 전송 |
| Base64 URL | SGk | JWT·URL 파라미터 |
| Hex | 4869 | 해시·암호화·디버깅 |
| Binary | 01001000 01101001 | 교육·로우레벨 분석 |
| URL Encoded | Hi (변경 없음) | 쿼리 스트링 (특수문자만 변환) |
| HTML Entity | Hi (변경 없음) | HTML 본문 안전 삽입 (<> 등) |
Base64는 암호화가 아닙니다
"Base64로 바꿔 두면 알아볼 수 없으니 안전하다"는 흔한 오해입니다. Base64는 키가 없는 인코딩이라 누구나 같은 규칙으로 즉시 되돌릴 수 있고,eyJ로 시작하거나 =로 끝나는 모양만 봐도 Base64임을 쉽게 알아챕니다.
- 비밀번호·API 키·카드 번호를 Base64로 "감춰서" 저장하거나 설정 파일에 넣는 것은 평문 저장과 같습니다.
- HTTP Basic 인증의
Authorization: Basic …값도user:password를 Base64로 바꾼 것일 뿐이라 HTTPS 없이 보내면 그대로 노출됩니다. - JWT의 PAYLOAD는 누구나 디코딩할 수 있으므로 민감 정보를 넣지 않습니다.
- 실제 보호가 필요하면 전송은 HTTPS(TLS), 저장 데이터는 암호화(AES 등), 비밀번호는 느린 해시(bcrypt·argon2)를 씁니다.
자주 묻는 질문
Base64로 인코딩하면 파일 크기가 왜 커지나요?
JWT 토큰을 디코딩해도 보안에 문제 없나요?
한글을 Base64로 인코딩하면 깨지는 이유는?
btoa()는 Latin-1(코드 0~255) 밖의 문자, 즉 한글·이모지를 넣으면 InvalidCharacterError가 납니다. 본 도구는 UTF-8로 먼저 변환한 후 Base64 인코딩하므로 한글·이모지·특수문자도 안전합니다. 디코딩 시에도 같은 방식으로 UTF-8을 되살려야 깨지지 않습니다. 새 코드라면 TextEncoder로 UTF-8 바이트를 만든 뒤 인코딩하는 방식을 권장합니다. 예전 코드에 흔한 btoa(unescape(encodeURIComponent(text)))는 폐기된 unescape에 기대는 레거시 패턴입니다.URL-safe Base64는 언제 사용하나요?
이미지를 Base64 Data URI로 임베드하는 게 좋을까요?
참고 자료
- RFC 4648 Base16·32·64 인코딩(새 창)rfc-editor.org
- RFC 2397 data URL(새 창)rfc-editor.org
- MDN btoa()(새 창)developer.mozilla.org
- 계산 기준
- RFC 4648(Base64·Base64URL) · RFC 2397(data URL) · 브라우저 btoa()/atob() 정의
- 오류 제보
- 결과가 다르면 contact@youtil.kr로 입력 조건을 알려 주세요. 평일 기준 1~3일 안에 답변합니다.