Base64 인코더·디코더
텍스트와 파일을 Base64로 인코딩하거나 디코딩합니다. 한글 등 유니코드와 URL-safe 방식도 지원합니다.
Base64는 암호화가 아닙니다. 누구나 되돌릴 수 있으므로 비밀번호나 토큰을 감추는 용도로 쓰면 안 됩니다.
Base64는 암호화가 아닙니다
가장 먼저 짚어야 할 점입니다. Base64는 누구나 되돌릴 수 있는 인코딩이며 비밀을 지켜주지 않습니다.
비밀번호나 API 키를 Base64로 감싸는 것은 보안 조치가 되지 못합니다. 어떤 도구로도 1초 만에 원본이 나옵니다. 실제로 유출 사고에서 "암호화했다"고 주장했다가 Base64였던 사례가 반복적으로 나옵니다.
암호화가 필요하다면 AES 같은 실제 암호 알고리즘을, 단방향 변환이 필요하다면 해시를 써야 합니다.
그럼 Base64는 왜 쓰나요
바이너리 데이터를 텍스트만 다룰 수 있는 통로로 옮기기 위해서입니다.
이메일(SMTP), JSON, XML, URL 같은 곳은 원래 텍스트를 전제로 설계되었습니다. 이미지나 실행 파일의 바이트를 그대로 넣으면 제어 문자 때문에 깨집니다.
Base64는 3바이트를 4개의 안전한 문자로 바꿔 이 문제를 해결합니다. 대신 데이터 크기가 약 33% 늘어납니다.
대표적인 용도는 이렇습니다.
- 이메일 첨부파일 — MIME 인코딩
- Data URI — HTML/CSS에 이미지를 직접 삽입 (
data:image/png;base64,...) - HTTP Basic 인증 — 사용자명:비밀번호를 Base64로 (그래서 HTTPS가 필수입니다)
- JWT — 헤더와 페이로드
- API 응답에 바이너리 담기
어떻게 바뀌는가
Base64는 64개의 문자만 씁니다. 대문자 26개, 소문자 26개, 숫자 10개에 +와 /를 더한 것입니다. 원본 바이트를 6비트씩 잘라 이 문자 하나에 대응시키므로, 3바이트(24비트)가 정확히 4문자가 됩니다.
| 원본 | 바이트 수 | Base64 | 결과 길이 |
| ---------- | --------- | ---------------------- | --------- |
| Man | 3 | TWFu | 4 |
| a | 1 | YQ== | 4 |
| ab | 2 | YWI= | 4 |
| 소이 | 6 (UTF-8) | 7IaM7J20 | 8 |
| 안녕하세요 | 15 (UTF-8) | 7JWI64WV7ZWY7IS47JqU | 20 |
한글은 한 글자가 UTF-8에서 3바이트라 글자당 정확히 4문자가 됩니다. 결과 길이는 항상 4의 배수이고, 바이트 수를 알면 길이를 미리 계산할 수 있습니다.
| 원본 크기 | Base64 길이 | 증가율 | | --------- | ----------- | ------ | | 100바이트 | 136자 | 36% | | 1KB | 1,368자 | 33.6% | | 1MB | 1,398,104자 | 33.3% |
도구 사용법
위 도구는 왼쪽에 넣은 내용을 오른쪽에 바로 변환합니다. 방향 버튼으로 인코딩과 디코딩을 오가고, 바꾸기 버튼은 결과를 입력 칸으로 옮겨 반대 방향으로 다시 변환합니다. 인코딩한 값이 제대로 돌아오는지 검산할 때 씁니다. URL-safe 스위치를 켜면 +와 /를 -와 _로 바꾸고 패딩을 뺀 형태로 만듭니다.
디코딩에 실패하는 흔한 원인은 다음과 같습니다.
- 앞에
data:image/png;base64,가 붙어 있음 — Data URI의 접두어입니다. 쉼표 뒤부터 붙여 넣어야 합니다. - 줄바꿈이 섞여 있음 — 이메일 첨부처럼 76자마다 줄을 바꾼 형식입니다. 이 도구는 공백과 줄바꿈을 무시하고 처리하지만, 다른 디코더에서는 오류가 날 수 있습니다.
- 복사가 잘림 — 길이가 4의 배수가 아니면 끝부분이 빠진 것입니다. 원본을 다시 복사하세요.
- Base64가 아닌 문자 — 한글이나
%가 섞여 있으면 Base64가 아니라 다른 인코딩입니다.%가 보이면 URL 인코더로 먼저 풀어야 합니다.
한글이 깨지는 이유
브라우저의 기본 함수 btoa()는 1바이트 문자만 처리합니다. 한글이나 이모지를 넣으면 예외가 발생하거나 깨진 결과가 나옵니다.
올바른 방법은 먼저 UTF-8로 인코딩한 뒤 Base64로 변환하는 것입니다. 이 도구는 그렇게 처리하므로 한글, 이모지, 일본어, 중국어 모두 정상적으로 왕복됩니다.
다른 곳에서 만든 Base64가 깨진다면, 그쪽에서 UTF-8 처리를 빠뜨렸을 가능성이 큽니다.
URL-safe Base64
표준 Base64는 +와 / 문자를 씁니다. 그런데 이 두 문자는 URL에서 다른 의미를 갖습니다. +는 공백으로 해석될 수 있고 /는 경로 구분자입니다.
그래서 URL에 담을 때는 URL-safe 변형을 씁니다.
| 표준 | URL-safe |
|---|---|
| + | - |
| / | _ |
| = 패딩 | 생략 |
JWT와 OAuth 토큰이 이 방식을 씁니다. 두 형식은 호환되지 않으므로 디코딩할 때 종류를 맞춰야 합니다. 이 도구는 -나 _가 보이면 자동으로 URL-safe로 판단해 디코딩합니다.
끝에 붙는 = 는 뭔가요
패딩입니다. Base64는 3바이트씩 묶어 4문자로 바꾸는데, 원본 길이가 3의 배수가 아니면 남는 자리가 생깁니다. 이를 =로 채워 전체 길이를 4의 배수로 맞춥니다.
- 원본이 3의 배수 → 패딩 없음
- 나머지 1바이트 →
== - 나머지 2바이트 →
=
패딩이 없어도 대부분의 디코더는 길이로 유추해 처리합니다. URL-safe 방식은 아예 패딩을 생략합니다.
명령줄과 코드에서 쓰기
도구 없이 바로 변환해야 할 때 자주 쓰는 명령입니다.
# macOS · Linux
echo -n "소이" | base64 # 인코딩
echo "7IaM7J20" | base64 -d # 디코딩
# Node.js
Buffer.from("소이").toString("base64")
Buffer.from("7IaM7J20", "base64").toString()
브라우저 자바스크립트의 btoa는 위에서 말한 대로 한글을 직접 받지 못하므로 TextEncoder로 UTF-8 바이트를 만든 뒤 넘겨야 합니다. 파이썬은 base64.b64encode("소이".encode())처럼 문자열을 먼저 바이트로 바꿔서 넘깁니다. 어느 언어든 문자열 → 바이트 → Base64 순서를 지키면 한글 문제가 생기지 않습니다.
이메일 제목이 =?UTF-8?B?...?=로 보일 때
메일 원문이나 로그에서 제목이 =?UTF-8?B?7IaM7J20?= 같은 형태로 보인다면, 이메일 헤더가 ASCII만 허용하기 때문에 한글 제목을 Base64로 감싼 것입니다. B?와 ?= 사이의 문자열만 잘라 이 도구에 넣으면 원래 제목이 나옵니다. ?Q?로 시작하면 Base64가 아니라 퍼센트 인코딩과 비슷한 Quoted-Printable 방식이므로 다른 도구가 필요합니다.
16진수·Base32와의 차이
바이너리를 텍스트로 표현하는 방법은 Base64만이 아닙니다. 16진수는 1바이트를 2문자로 표현해 길이가 두 배가 되지만 사람이 읽고 비교하기 쉬워 해시값 표기에 쓰입니다. Base32는 대소문자를 구분하지 않아도 되어 손으로 옮겨 적는 코드나 OTP 비밀키에 쓰입니다. Base64는 셋 중 가장 짧아 전송 효율이 좋은 대신 대소문자를 구분하고 +·/ 때문에 URL에서 손질이 필요합니다. 어디에 넣을 것인지에 따라 고르면 됩니다.
Data URI로 이미지 넣기
작은 아이콘을 HTML에 직접 넣을 때 씁니다.
<img src="data:image/png;base64,iVBORw0KGgo...">
HTTP 요청 하나를 줄일 수 있어 아주 작은 이미지에는 유리합니다. 다만 크기가 33% 늘고 브라우저 캐시를 활용할 수 없어, 몇 KB를 넘는 이미지에는 오히려 손해입니다.
함께 확인하면 좋은 것
JWT 토큰의 내용을 보려면 JWT 디코더가 편합니다. 되돌릴 수 없는 변환이 필요하다면 해시 생성기를, JSON 정리는 JSON 포맷터를 이용하세요.
자주 묻는 질문
더 읽을 글
- JWT 구조와 검증 — 디코딩과 서명 확인의 차이
예시 토큰을 헤더·페이로드·서명으로 분해해 각 부분의 생성 원리, 페이로드를 바꾸면 서명이 맞지 않는 이유, alg none과 알고리즘 혼동 공격, Base64와 Base64URL 차이, 서버가 토큰을 받아들이는 다섯 단계 검증 순서, HS256·RS256·ES256 선택 기준을 정리했습니다.
- JSON 파싱 오류 원인별 해결 — 브라우저마다 다른 메시지
크롬(V8)·파이어폭스(SpiderMonkey)·사파리(JavaScriptCore)가 같은 JSON 오류에 내는 실제 메시지를 원인별로 대조하고, 메시지에서 원인으로 역추적하는 법, HTML이 온 경우, 큰 정수가 바뀌는 문제, 오류 문구를 코드에서 다룰 때의 주의점을 정리했습니다.