Base64 URL-safe

URL 안전 Base64(Base64url) 인코딩 및 디코딩

일반 텍스트

Base64

로컬에서 실행 · 시크릿 붙여넣기 안전
Base64 출력...

Base64url 인코딩이란?

Base64url은 URL, 파일명, 표준 Base64 문자인 +와 /가 문제를 일으키는 기타 컨텍스트에서 사용하도록 설계된 Base64 인코딩의 변형입니다. RFC 4648 섹션 5에 정의된 Base64url은 +를 -(하이픈)으로, /를 _(언더스코어)로 대체하고 후행 = 패딩 문자를 생략합니다. 결과 문자열은 추가적인 퍼센트 인코딩 없이 URL 쿼리 파라미터, 파일명, HTTP 헤더에 직접 삽입할 수 있습니다.

표준 Base64(RFC 4648 섹션 4)는 64개의 문자를 사용합니다: A-Z, a-z, 0-9, +, /. +와 / 문자는 URL에서 예약된 문자입니다: +는 쿼리 문자열(application/x-www-form-urlencoded)에서 공백으로 해석되고, /는 경로 구분자입니다. 따라서 URL 내에서 표준 Base64를 사용하려면 이 문자들을 퍼센트 인코딩(%2B, %2F)해야 하므로 문자열 길이가 늘어나고 가독성이 떨어집니다. Base64url은 처음부터 URL에 안전한 문자를 사용하여 이 문제를 완전히 해소합니다.

Base64url의 가장 대표적인 사용 사례는 JSON Web Token(JWT)입니다. JWT의 세 세그먼트 — 헤더, 페이로드, 서명 — 모두 Base64url로 인코딩됩니다. OAuth 2.0 PKCE code verifier, WebAuthn 챌린지 값, 그리고 많은 API 토큰 체계도 Base64url에 의존합니다. 인증, 권한 부여, 또는 암호화 데이터 교환을 다루는 개발자라면 이 인코딩 방식을 이해하는 것이 필수적입니다.

이 Base64url 도구를 사용하는 이유

브라우저에서 직접 Base64url과 텍스트 또는 바이너리 데이터 간을 변환합니다. 인코딩과 디코딩 모두 지원하며, 패딩 및 문자 대체를 자동으로 처리합니다. JWT 토큰을 디버깅하거나, PKCE 코드 챌린지를 생성하거나, URL 안전 식별자를 구축하는 경우에도 이 도구는 브라우저에서 로컬로 모든 처리를 수행하므로 지연 없이 서버 왕복 없이 즉시 결과를 얻을 수 있습니다.

즉시 변환
입력하는 즉시 출력이 업데이트됩니다. 텍스트를 Base64url로 인코딩하거나 Base64url을 텍스트로 디코딩할 때 지연 없음 — 폼 제출이나 페이지 새로고침 불필요.
🔗
URL 안전 출력
출력은 URL, 파일명, HTTP 헤더에서 안전한 문자만 사용합니다: A-Z, a-z, 0-9, 하이픈, 언더스코어. 퍼센트 인코딩 불필요.
🔒
개인정보 우선 처리
모든 인코딩 및 디코딩은 브라우저에서 로컬로 실행됩니다. 여기에 붙여넣은 JWT 토큰, OAuth 비밀, API 키는 어떤 서버에도 전송되지 않습니다.
🏛️
표준 준수
RFC 4648 섹션 5를 정확하게 구현합니다: -와 _가 +와 /를 대체하고 패딩이 생략됩니다. JWT 라이브러리, OAuth 2.0 PKCE, WebAuthn 구현과 호환됩니다.

Base64url 활용 사례

JWT 토큰 검사
JWT 라이브러리를 가져오거나 서명을 검증하지 않고도 개별 JWT 세그먼트(헤더, 페이로드)를 디코딩하여 클레임, 만료 시간, 서명 알고리즘을 확인합니다.
OAuth 2.0 PKCE 흐름
PKCE code_verifier와 code_challenge 값을 생성하고 검증합니다. code_challenge_method S256은 code_verifier의 SHA-256 해시를 Base64url로 인코딩해야 합니다.
WebAuthn / FIDO2 통합
WebAuthn 챌린지, 자격 증명 ID, 증명 데이터는 브라우저와 신뢰 당사자 서버 간에 Base64url 문자열로 전송됩니다. 등록 및 인증 흐름을 디버깅하기 위해 디코딩합니다.
API 토큰 생성
임의 바이트로부터 URL 안전 토큰을 생성하여 비밀번호 재설정 링크, 이메일 인증, 세션 식별자에 활용합니다. Base64url은 이스케이프 없이 URL에서 작동하는 간결한 문자열을 생성합니다.
DevOps 및 CI/CD 파이프라인
바이너리 구성 값(인증서, 키)을 환경 변수나 YAML 파일에 Base64url 문자열로 저장합니다. 표준 Base64와 달리 출력에 쉘 확장이나 YAML 구문과 충돌하는 문자가 포함되지 않습니다.
데이터 엔지니어링
바이너리 식별자, 해시, 체크섬을 Base64url로 인코딩하여 파일명, 데이터베이스 키, CSV 컬럼에 사용합니다. +와 / 문자가 파싱을 방해하거나 이스케이프가 필요한 문제를 해소합니다.

표준 Base64 vs Base64url

Base64url은 표준 Base64와 정확히 세 가지 면에서 다릅니다. 인코딩 알고리즘은 동일하며 — 알파벳과 패딩 동작만 변경됩니다:

특징표준 (RFC 4648 §4)Base64url (RFC 4648 §5)
Index 62+-
Index 63/_
Padding= (required)Omitted

이 세 가지 차이점 덕분에 표준 Base64와 Base64url 간 변환은 간단합니다: +를 -로, /를 _로 교체하고 후행 = 문자를 제거합니다. 반대로는 -를 +로, _를 /로 교체하고 길이가 4의 배수가 되도록 패딩을 다시 추가합니다. 대부분의 언어는 네이티브 Base64url 지원을 제공하므로 수동 변환이 불필요합니다. 두 변환 모두 완전히 역변환 가능하며 손실이 없어 원본 바이트 시퀀스를 정확히 보존합니다. 이 상호 운용성은 RFC 4648에 의해 보장됩니다.

인코딩 비교 표

아래 표는 표준 Base64와 Base64url로 인코딩된 동일한 입력을 보여줍니다. URL 안전 변형에서 패딩 문자(=)가 제거되고 +와 /가 -와 _로 대체되는 것을 확인하세요:

입력표준 Base64Base64url (패딩 없음)
HelloSGVsbG8=SGVsbG8
AQQ==QQ
1+1=2MSsxPTI=MSsxPTI
subject?ref=1c3ViamVjdD9yZWY9MQ==c3ViamVjdD9yZWY9MQ
👍 (thumbs up)8J+RjQ==8J-RjQ

코드 예제

인기 있는 언어에서 Base64url 문자열을 인코딩하고 디코딩하는 방법. 모든 예제는 URL, 파일명, HTTP 헤더에서 안전하게 사용할 수 있는 출력을 생성합니다:

JavaScript (browser)
// Encode to Base64url
function toBase64url(str) {
  return btoa(unescape(encodeURIComponent(str)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '')
}
toBase64url('Hello!') // → "SGVsbG8h"

// Decode from Base64url
function fromBase64url(b64url) {
  const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/')
  const pad = (4 - b64.length % 4) % 4
  return decodeURIComponent(escape(atob(b64 + '='.repeat(pad))))
}
fromBase64url('SGVsbG8h') // → "Hello!"
Node.js
// Native base64url support since Node 15.7
const encoded = Buffer.from('Hello!').toString('base64url')
// → "SGVsbG8h"

const decoded = Buffer.from('SGVsbG8h', 'base64url').toString()
// → "Hello!"

// Decode a JWT payload
const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0...'
const payload = JSON.parse(Buffer.from(jwt.split('.')[1], 'base64url').toString())
// → { sub: "1234567890" }
Python
import base64

# Encode to Base64url (no padding)
encoded = base64.urlsafe_b64encode(b'Hello!').rstrip(b'=').decode()
# → "SGVsbG8h"

# Decode from Base64url (re-add padding)
def b64url_decode(s: str) -> bytes:
    s += '=' * (4 - len(s) % 4)  # restore padding
    return base64.urlsafe_b64decode(s)

b64url_decode('SGVsbG8h')  # → b'Hello!'
Go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    // Encode to Base64url (no padding)
    encoded := base64.RawURLEncoding.EncodeToString([]byte("Hello!"))
    fmt.Println(encoded) // → "SGVsbG8h"

    // Decode from Base64url
    decoded, _ := base64.RawURLEncoding.DecodeString("SGVsbG8h")
    fmt.Println(string(decoded)) // → "Hello!"
}

자주 묻는 질문

Base64와 Base64url의 차이점은 무엇인가요?
Base64url은 표준 Base64 알파벳에서 +를 -로, /를 _로 대체하고 후행 = 패딩 문자를 생략합니다. 이로 인해 추가 인코딩 없이 URL, 쿼리 파라미터, 파일명, HTTP 헤더에서 안전하게 사용할 수 있습니다. 기본 알고리즘(바이트를 6비트 그룹으로 나누어 ASCII 문자에 매핑)은 동일합니다. 실제로 Base64url 문자열은 수정 없이 URL과 HTTP 헤더에 직접 사용할 수 있는 반면, 표준 Base64 문자열은 해당 컨텍스트에서 퍼센트 인코딩(+는 %2B, /는 %2F)이 필요합니다.
JWT 토큰은 왜 표준 Base64 대신 Base64url을 사용하나요?
JWT는 URL 쿼리 파라미터와 HTTP Authorization 헤더로 자주 전송됩니다. 표준 Base64 문자인 +와 /는 URL에서 퍼센트 인코딩이 필요하여 길이가 늘어나고 단순한 문자열 비교가 어려워집니다. JWT 명세(RFC 7519)는 토큰이 기본적으로 간결하고 URL에 안전하도록 패딩 없는 Base64url을 의무화합니다.
표준 Base64를 Base64url로 어떻게 변환하나요?
모든 +를 -로, /를 _로 교체하고 후행 = 문자를 모두 제거합니다. JavaScript에서는: base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''). Python에서는: base64.urlsafe_b64encode(data).rstrip(b'='). 대부분의 최신 언어는 전용 Base64url 인코딩 함수도 제공합니다. 이 변환은 표준 Base64를 출력하는 구형 라이브러리를 Base64url을 기대하는 최신 시스템과 통합할 때 흔히 필요합니다.
Base64url 인코딩은 역변환이 가능한가요?
네, Base64url은 완전히 역변환 가능합니다. 디코딩하려면 -를 +로, _를 /로 교체하고 길이가 4의 배수가 되도록 = 패딩을 다시 추가한 다음 표준 Base64로 디코딩합니다. 디코딩된 출력은 원본 입력과 바이트 단위로 동일합니다.
Base64url을 데이터 암호화에 사용할 수 있나요?
아니요. Base64url은 암호화가 아닌 인코딩입니다. 비밀 없이 바이너리 데이터를 텍스트 안전 형식으로 변환하며 — 누구나 디코딩할 수 있습니다. 데이터를 보호해야 한다면 먼저 적절한 알고리즘(AES, ChaCha20)으로 암호화한 후 전송을 위해 암호문을 Base64url로 인코딩하세요.
Base64url에서 패딩이 생략되는 이유는 무엇인가요?
패딩 문자(=)는 디코더가 문자열 길이로 누락된 바이트 수를 계산할 수 있으므로 실질적인 역할이 없습니다: (4 - 길이 % 4) % 4가 필요한 패딩을 알려줍니다. 패딩을 생략하면 문자열이 짧아지고 URL에서 퍼센트 인코딩이 필요한 = 문자를 피할 수 있습니다. RFC 4648 섹션 5는 Base64url에서 패딩 생략을 명시적으로 허용합니다.
코드에서 패딩이 있는 Base64url 문자열을 어떻게 처리하나요?
일부 시스템은 = 패딩을 유지하는 Base64url 문자열을 생성합니다. 대부분의 디코더는 이를 올바르게 처리합니다. 그렇지 않은 경우 디코딩 전에 후행 =를 제거하세요. 반대로 라이브러리가 패딩을 요구하는 경우 계산하여 추가하세요: const padded = str + '='.repeat((4 - str.length % 4) % 4). 패딩 수는 문자열 길이로 결정적으로 계산되므로 이 방법은 항상 유효합니다.