인코딩

Base64 인코딩 완벽 이해: 원리, 쓰임새, 흔한 오해

이메일 첨부파일, 이미지 data URI, JWT 토큰까지. 개발을 하다 보면 Base64 문자열을 매일 마주칩니다. 이 글에서는 Base64가 정확히 무엇을 하는지, 왜 결과가 원본보다 길어지는지, 언제 써야 하고 언제 쓰면 안 되는지를 정리합니다.

Base64는 왜 필요한가

컴퓨터의 모든 데이터는 결국 0과 1로 이루어진 바이트입니다. 그런데 이메일, HTTP 헤더, JSON, URL처럼 '텍스트'만 안전하게 오갈 수 있는 통로가 의외로 많습니다. 이런 통로에 이미지 파일이나 암호화된 바이트를 그대로 넣으면 제어 문자나 줄바꿈이 섞여 데이터가 깨지거나, 중간 시스템이 내용을 임의로 바꿔 버릴 수 있습니다.

Base64는 어떤 바이트든 영문 대소문자, 숫자, 그리고 +와 / 두 기호만으로 이루어진 64개 문자 집합으로 바꿔서 이 문제를 해결합니다. 이 64개 문자는 거의 모든 시스템에서 '안전한 글자'로 취급되기 때문에, 바이너리 데이터를 텍스트 통로로 안전하게 실어 나를 수 있습니다. 표준은 RFC 4648에 정의되어 있습니다.

3바이트를 4글자로: 동작 원리

Base64의 핵심은 단순합니다. 입력을 3바이트(24비트)씩 묶은 뒤, 이 24비트를 6비트씩 네 조각으로 나눕니다. 6비트로 표현할 수 있는 값은 0부터 63까지 64가지이므로, 각 조각을 64개 문자표의 한 글자에 대응시키면 됩니다. 0~25는 A~Z, 26~51은 a~z, 52~61은 0~9, 62는 +, 63은 /입니다.

예를 들어 영어 단어 Man은 M, a, n 세 글자이고 각각 77, 97, 110이라는 바이트 값을 가집니다. 이 24비트를 6비트씩 나누면 19, 22, 5, 46이 되고, 문자표에 대응시키면 TWFu가 됩니다. 한글도 마찬가지입니다. '한'은 UTF-8로 3바이트(ED 95 9C)이므로 정확히 4글자인 7ZWc가 됩니다.

Man   → TWFu
Hi    → SGk=
한    → 7ZWc
안녕  → 7JWI64WV

이 구조 때문에 Base64 결과는 항상 원본보다 약 33% 길어집니다. 3바이트가 4글자가 되니까요. 1,000바이트 파일을 인코딩하면 1,336글자가 됩니다. 큰 이미지를 data URI로 HTML에 박아 넣으면 페이지가 눈에 띄게 무거워지는 이유가 바로 이것입니다.

끝에 붙는 = 기호의 정체

입력 길이가 3의 배수가 아니면 마지막 묶음이 1바이트나 2바이트만 남습니다. 이때 부족한 비트를 0으로 채워 인코딩하고, 결과 길이를 4의 배수로 맞추기 위해 = 기호를 붙입니다. 1바이트가 남으면 ==, 2바이트가 남으면 = 하나가 붙습니다. 위 예시에서 Hi(2바이트)가 SGk=로 끝나는 이유입니다.

패딩은 디코더가 원래 길이를 정확히 복원하도록 돕는 표시일 뿐 데이터가 아닙니다. 일부 시스템은 패딩을 생략하기도 하는데, 이런 문자열을 엄격한 디코더에 넣으면 '잘못된 길이' 오류가 날 수 있습니다. 이럴 때는 길이가 4의 배수가 되도록 끝에 =를 다시 채워 주면 대부분 해결됩니다.

Base64URL: URL과 파일명에 쓰는 변형

표준 Base64의 +와 /는 URL에서 특별한 의미를 가집니다. +는 공백으로 해석될 수 있고, /는 경로 구분자입니다. 그래서 URL이나 파일명에 넣을 때는 +를 -로, /를 _로 바꾼 Base64URL 변형을 씁니다. 같은 바이트(FB FF)를 표준 방식으로 인코딩하면 +/8=, Base64URL로 인코딩하면 -_8=가 됩니다.

JWT(JSON Web Token)의 세 부분이 모두 Base64URL로 인코딩되어 있고, 보통 패딩도 생략합니다. JWT의 가운데 부분을 디코딩하면 사용자 ID나 만료 시간 같은 내용을 그대로 읽을 수 있는데, 이것이 다음 절에서 말할 '암호화가 아니다'의 좋은 예입니다.

가장 흔한 오해: Base64는 암호화가 아니다

Base64 문자열은 사람이 보기에 무작위처럼 보여서 종종 '암호화'로 오해받습니다. 하지만 Base64에는 비밀 키가 없고, 누구나 같은 규칙으로 즉시 원문을 되돌릴 수 있습니다. 비밀번호나 API 키를 Base64로 바꿔 저장하거나 전송하는 것은 평문으로 두는 것과 보안상 차이가 없습니다.

HTTP Basic 인증 헤더가 대표적입니다. 아이디와 비밀번호를 콜론으로 이어 Base64로 인코딩해 보내지만, 이는 전송 형식일 뿐이고 실제 보호는 HTTPS가 담당합니다. 데이터를 숨겨야 한다면 AES 같은 암호화를, 위변조를 확인해야 한다면 해시나 서명을 써야 합니다.

실무에서 자주 만나는 Base64

Base64는 생각보다 많은 곳에 숨어 있습니다. 어디서 쓰이는지 알아 두면 낯선 문자열을 만났을 때 정체를 빠르게 파악할 수 있습니다.

  • 이메일 첨부파일: MIME 규격은 바이너리 첨부를 Base64로 인코딩해 본문에 포함합니다.
  • data URI: 작은 아이콘을 data:image/png;base64,... 형태로 CSS나 HTML에 직접 넣습니다. 수 KB 이하의 작은 이미지에만 권장합니다.
  • JWT와 OAuth: 토큰의 헤더와 페이로드가 Base64URL입니다.
  • API 요청 본문: JSON은 바이너리를 담을 수 없어서 파일이나 서명 값을 Base64 문자열로 넣습니다.
  • 인증서와 키 파일: -----BEGIN CERTIFICATE----- 로 시작하는 PEM 파일의 본문이 Base64입니다.

디코딩이 안 될 때 확인할 것

Base64 디코딩 오류의 대부분은 몇 가지 원인으로 정리됩니다. 먼저 문자열에 줄바꿈이나 공백이 섞여 있지 않은지 확인하세요. 이메일이나 PEM 파일은 76자마다 줄을 바꾸는 경우가 많습니다. 다음으로 -나 _가 보이면 Base64URL이므로 해당 방식으로 디코딩해야 합니다. 마지막으로 길이가 4의 배수가 아니면 패딩이 빠진 것입니다.

디코딩은 성공했는데 글자가 깨져 보인다면 원본의 문자 인코딩 문제입니다. 한글은 UTF-8과 EUC-KR에서 바이트가 완전히 다르기 때문에, 인코딩할 때와 같은 문자셋으로 해석해야 합니다. AIBIZAP의 Base64 도구는 UTF-8을 기준으로 처리하므로 한글, 일본어, 이모지도 깨지지 않고 변환됩니다.

이 도구로 직접 해 보세요

다른 가이드

전체 가이드