Base64URL にエンコードする手順
- テキストを 入力 · テキスト に入力するか貼り付けます。
- 出力 · Base64 から Base64URL をコピーします。このページでは URLセーフ(- _) と パディングなし(=) に最初からチェックが入っています。
- 受け取る側がパディングを求めるなら、パディングなし(=) のチェックを外します。標準の Base64 が必要なら URLセーフ のチェックも外すか、Base64 エンコーダー を使ってください。
- 出力をコピーするか、
base64.txtとしてダウンロードします。
値のデコードには Base64URL デコーダー を使います。既存の文字列を 2 つのアルファベットの間で変換するのは Base64 から Base64URL へ です。
標準の Base64 との違い
異なるのは 3 文字だけです。3 バイトを 4 文字にするルールも含め、それ以外はすべて同じです。
| 標準の Base64 | Base64URL | |
|---|---|---|
| 値 62 | + | - |
| 値 63 | / | _ |
| パディング | = が必須 | 通常は省略 |
| 定義 | RFC 4648 第 4 節 | RFC 4648 第 5 節 |
短い文字列の多くでは、2 つのバリアントの違いはパディングだけです。アルファベットの違いが表れるのは、6 ビットのグループの値が 62 か 63 になるときで、? や > のような文字や、ASCII 以外の多くのバイトがこれに当たります。
| 入力 | 標準 | Base64URL、パディングなし |
|---|---|---|
Hi! | SGkh | SGkh |
?>?> | Pz4/Pg== | Pz4_Pg |
subjects?_d | c3ViamVjdHM/X2Q= | c3ViamVjdHM_X2Q |
https://example.com/?q=1 | aHR0cHM6Ly9leGFtcGxlLmNvbS8/cT0x | aHR0cHM6Ly9leGFtcGxlLmNvbS8_cT0x |
経緯とデコード時の違いは、Base64 と Base64URL の違い で詳しく説明しています。
URL に専用のアルファベットが必要な理由
標準の 3 文字は、どれも URL の中で意味を持ちます。/ はパスのセグメントを区切り、= はクエリ文字列で名前と値を区切り、+ はフォームのデコーダーに空白として読まれます。クエリパラメーターに入れた a+b/c== のような標準の Base64 の値は、すべての文字をエスケープしない限り a b/c== として届きます。パーセントエンコードで解決できますが、それぞれが 3 文字(%2B、%2F、%3D)になります。
Base64URL は URL で予約されていない 2 文字を選び、パディングも省くので、値をパス、クエリ文字列、フラグメント、Cookie、ファイル名にそのまま貼り付けられます。- と _ は / と違い、一般的などのファイルシステムでもファイル名に安全に使えます。
Base64URL が使われている場所
- JWT と JOSE。 JSON Web Token の各部分は、RFC 7515 で定義されたパディングなしの Base64URL です。トークンは JWT デコーダー で読めます。構造は JWT の Base64 で解説しています。
- OAuth の PKCE。
code_challengeは、code_verifierの SHA-256 ハッシュを Base64URL にしたものです。 - WebAuthn とパスキー。 クレデンシャル ID とチャレンジは、JSON の中で Base64URL として送られます。
- リンクと ID。 共有リンク、署名付き URL パラメーター、ランダムなバイト列から作る短い ID は、URL をきれいに保つためにこれを使います。
コードで Base64URL を扱う
Node.js には組み込みの base64url エンコーディングがあり、Python には URL セーフな関数があります(パディングは自分で取り除きます)。
// Node.js
Buffer.from("subjects?_d").toString("base64url"); // "c3ViamVjdHM_X2Q"
// Browsers with Uint8Array.prototype.toBase64
new TextEncoder().encode("subjects?_d").toBase64({ alphabet: "base64url", omitPadding: true });
import base64, hashlib
base64.urlsafe_b64encode(b"subjects?_d").rstrip(b"=").decode() # 'c3ViamVjdHM_X2Q'
# PKCE code_challenge, example from RFC 7636 appendix B
verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
digest = hashlib.sha256(verifier.encode("ascii")).digest()
base64.urlsafe_b64encode(digest).rstrip(b"=").decode()
# 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'
詳しくは Node.js での Base64、JavaScript、Python を、ブラウザの API については Uint8Array.toBase64 をご覧ください。
よくある質問
Base64URL とは何ですか?
RFC 4648 の第 5 節で定義された、URL とファイル名で安全に使える Base64 のバリアントです。アルファベットの最後の 2 文字に + と / ではなく - と _ を使い、通常は = のパディングなしで書かれます。
普通の Base64 をパーセントエンコードするだけではだめですか?
それでも動きますが、+、/、= の 1 つごとに 3 文字かかり、エスケープし忘れるとクエリ文字列の解析時に + が空白になります。Base64URL ならどちらの問題も起きません。
= のパディングは残すべきですか?
JWT や大半の URL セーフな形式では省略します。= も URL ではエスケープが必要で、デコーダーは長さからパディングを割り出せるからです。受け取る側が要求する場合にだけ残してください。その場合は「パディングなし」のチェックを外します。
PKCE の code_challenge はどう作りますか?
code_verifier を SHA-256 でハッシュし、32 バイトのハッシュ値をパディングなしで Base64URL エンコードします。このページがエンコードするのはハッシュのバイト列ではなくテキストなので、コードで行ってください。下のスニペットで RFC 7636 の例を再現できます。