Base64 URL 안전 인코딩: 정의와 중요성
Base64 URL 안전 인코딩이란?
Base64 URL 안전 인코딩(Base64url이라고도 함)은 URL과 파일 이름에서 특별한 의미를 가지는 문자들을 안전한 대체 문자로 바꾼 표준 Base64의 변형입니다. 표준 Base64는 64자 알파벳의 일부로 +와 /를 사용하고 패딩으로 =를 사용하는데, 이 세 문자 모두 URL, 쿼리 문자열, 파일 경로에서 문제가 됩니다.
Base64url은 두 가지 간단한 치환으로 이 문제를 해결합니다:
| 표준 Base64 | URL 안전 Base64 |
|-----------------|-----------------|
| + (더하기) | - (빼기) |
| / (슬래시) | _ (밑줄) |
| = (패딩) | 생략 (일반적) |
표준 Base64가 URL을 깨뜨리는 이유
+나 /가 포함된 Base64 인코딩 문자열이 URL에 나타나면, 브라우저와 서버의 동작이 예측 불가능해집니다.
+ 문제
URL 쿼리 문자열에서 + 문자는 공백으로 해석됩니다. 이 동작은 application/x-www-form-urlencoded 명세에서 비롯되며, 디코딩된 데이터에 예상치 못한 공백이 생기게 합니다.
예를 들어, Pj4+Pz8/Pw==와 같은 Base64 문자열에는 + 문자가 포함되어 있습니다. 이것이 URL 매개변수 ?token=Pj4+Pz8/Pw==에 나타나면, 서버는 ?token=Pj4 Pz8/Pw==로 인식합니다 — +가 공백이 됩니다.
/ 문제
URL 경로에서 / 문자는 경로 구분자입니다. ab/CD+Ef==와 같은 Base64 문자열에는 /가 포함되어 있어 디렉터리 레벨로 해석됩니다. 이것이 URL 세그먼트에 나타나면 클라이언트와 서버 모두 구조를 잘못 해석할 수 있습니다.
= 문제
= 문자는 쿼리 문자열에서 키-값 쌍에 사용됩니다. ?data=SGVsbG8=의 마지막 =은 모호할 수 있습니다 — =이 Base64 패딩의 일부인가요, 아니면 쿼리 매개변수 구문인가요?
퍼센트 인코딩으로 이러한 문제를 해결할 수 있지만(+는 %2B로, /는 %2F로), 문자열 길이가 늘어나고 디버깅이 더 어려워집니다. Base64url이 더 깔끔한 해결책입니다.
Base64url의 작동 방식
Base64url은 RFC 4648 섹션 5에 공식적으로 정의되어 있습니다. 표준 Base64와 정확히 동일한 알고리즘(3바이트가 4문자가 됨)을 사용하지만, 알파벳의 62번과 63번 위치에서 한 문자씩 치환합니다:
- 알파벳 인덱스 62:
+→-(빼기) - 알파벳 인덱스 63:
/→_(밑줄)
패딩(=)은 일반적으로 제거되는데, 디코딩 시 문자열 길이로부터 추론할 수 있기 때문입니다. Base64url 문자열은 추가 이스케이프 없이 항상 유효한 URL 구성 요소입니다.
변환 전후
다음은 동일한 이진 데이터가 두 형식에서 어떻게 보이는지 보여줍니다:
표준: Pj4+Pz8/Pw==
URL 안전: Pj4-Pz8_Pw
Base64url이 사용되는 곳
JSON Web Token (JWT)
JWT는 Base64url의 가장 대표적인 사용처입니다. 모든 JWT는 헤더, 페이로드, 서명의 세 부분으로 구성되며, 각각 URL 안전 Base64로 인코딩되고 점으로 구분됩니다:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNqP0m2iTgCjD0
대시와 밑줄이 보이고 더하기 기호나 슬래시가 없는 것을 확인할 수 있습니다. JWT가 표준 Base64를 사용했다면, 웹 애플리케이션에서 가장 일반적인 사용 방식인 URL 매개변수로 전달될 때 토큰이 깨질 것입니다.
OAuth 및 OpenID Connect
OAuth 2.0과 OpenID Connect 모두 액세스 토큰과 ID 토큰에 JWT를 사용하므로, Base64url 인코딩은 현대 인증의 기본입니다. 인증 코드 플로우, 암시적 플로우, 클라이언트 자격 증명 플로우 모두 Base64url을 사용하는 토큰을 전송합니다.
웹 API 및 쿼리 매개변수
많은 REST 및 GraphQL API가 페이지네이션 커서, 필터 또는 인코딩된 페이로드를 위해 쿼리 매개변수에 Base64 인코딩 데이터를 허용합니다. Base64url은 이러한 매개변수가 추가 URL 인코딩 없이 올바르게 작동하도록 보장합니다.
실제 사례 — API 커서 페이지네이션:
GET /api/users?cursor=MjAyNC0wMS0xNVQxMDozMDowMFo
GitHub의 API는 대량 결과 집합을 페이지네이션할 때 이와 정확히 동일한 패턴을 사용합니다.
파일 이름 및 파일 저장소
Base64url 문자열은 경로 구분자(/)를 포함하지 않고, 파일 시스템을 혼란스럽게 하는 특수 문자도 없으며, Windows에서 유효하지 않은 문자(:, *, ? 등)도 포함하지 않으므로 안전한 파일 이름이 됩니다.
콘텐츠 전송 네트워크 및 캐시 키
CDN과 캐싱 계층은 종종 Base64url로 인코딩된 값을 캐시 키로 사용합니다. /가 포함된 표준 Base64는 캐시 네임스페이스에 가짜 디렉터리 계층 구조를 만들어 모호한 키를 생성할 수 있습니다.
표준 Base64와 Base64url 간 변환
두 변형 간 변환은 어떤 언어에서든 간단합니다:
JavaScript
// Standard Base64 to URL-safe Base64
function base64ToBase64url(base64) {
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
// URL-safe Base64 to Standard Base64
function base64urlToBase64(base64url) {
let result = base64url.replace(/-/g, '+').replace(/_/g, '/');
// Restore padding
while (result.length % 4) {
result += '=';
}
return result;
}
Node.js
Node.js는 버전 15.7.0부터 네이티브 Base64url 지원을 제공합니다:
// Encode to Base64url
const encodedUrl = Buffer.from('Hello, world!').toString('base64url');
console.log(encodedUrl);
// Output: SGVsbG8sIHdvcmxkIQ
// Decode from Base64url
const decoded = Buffer.from(encodedUrl, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Python
import base64
# Encode to Base64url
encoded = base64.urlsafe_b64encode(b"Hello, world!")
print(encoded.decode())
# Output: SGVsbG8sIHdvcmxkIQ==
# Decode from Base64url
decoded = base64.urlsafe_b64decode(encoded)
print(decoded.decode())
# Output: Hello, world!
표준 Base64 vs Base64url 사용 시기
표준 Base64를 사용해야 하는 경우:
- 이메일 첨부 파일 인코딩 (MIME 표준에서 요구)
- HTML/CSS 임베딩용 데이터 URL 생성
- URL 안전성이 중요하지 않은 데이터베이스에 데이터 저장
- 표준 Base64를 기대하는 레거시 시스템과의 상호 작용
Base64url을 사용해야 하는 경우:
- JWT 토큰 생성 또는 파싱
- URL 쿼리 매개변수나 경로 세그먼트에 인코딩된 데이터 전달
- 이진 데이터로부터 파일 이름 생성
- 캐시 키나 식별자 생성
- OAuth 토큰 또는 OpenID Connect 작업
온라인으로 Base64 URL 안전 인코딩 체험하기
무료 온라인 Base64 인코더 및 디코더를 사용하여 표준 Base64와 URL 안전 Base64 형식 간에 변환하세요. 데이터를 붙여넣고 원하는 변형을 선택하면 즉시 결과를 얻을 수 있습니다.