Base64 が実際に行っていること
Base64 は、64 文字のアルファベット(A–Z、a–z、0–9、'+'、'/')を使ってバイナリデータをテキストとして表現するエンコーディングです。入力の 3 バイト(24 ビット)を 6 ビットずつ 4 グループに分割し、各グループを 1 文字にマッピングします。したがって出力サイズは入力の約 4/3(約 33% 増)になります。出力長を 4 の倍数にそろえるため、パディング文字「=」が末尾に付くこともあります。
なぜ存在するのか — テキスト専用トランスポート
多くのプロトコルやストレージ形式はテキストを前提として設計されており、任意のバイナリデータを安全に運べません。メール(MIME)・HTTP ヘッダー・JSON・XML・URL クエリ文字列などは、改行コード・制御文字・文字エンコーディングの問題でそのままバイナリを載せられません。Base64 を使えば、画像・証明書・アーカイブ・暗号化トークンなどのバイナリを、これらのテキスト前提コンテキストに安全に埋め込めます。
代表的な使い方
- CSS や HTML に画像を data: URL として直接埋め込む。
- JWT(JSON Web Token)のヘッダー・ペイロードをエンコードして HTTP ヘッダーで送信する。
- MIME エンコードされたメールでバイナリ添付を運ぶ。
- JSON API のレスポンスに小さなバイナリ(画像・署名など)を含める。
- PEM 形式の証明書や鍵を表現する(PEM は Base64 にヘッダー・フッター行を加えたもの)。
- HTTP Basic 認証の Authorization ヘッダーで資格情報をエンコードする。
Base64 は暗号化ではない
最もよくある誤解です。Base64 は完全に可逆なエンコーディングであり、エンコード後の文字列を持っている人は誰でも瞬時に元のバイト列に復号できます(鍵は不要です)。Base64 でパスワード・API トークン・その他の秘密情報を「隠した」つもりになっても、セキュリティ上の保護はゼロです。データを保護したい場合は、AES-GCM、age、libsodium など本物の暗号化を使ってください。Base64 はあくまでもトランスポート用のエンコーディングです。
URL セーフ Base64 と他のバリアント
標準 Base64 のアルファベットには「+」と「/」が含まれますが、これらは URL 内で特別な意味を持ちます。URL セーフバリアント(RFC 4648 定義)では、それぞれ「-」と「_」に置き換えられ、「=」パディングが省略されることもよくあります。JWT は URL セーフ Base64 を使用します。他にもパディングなしの Base64url、Base32(DNS や TOTP シークレットで使用)、Base58(Bitcoin で使用)などのバリアントがあります。エンコード/デコード前に、どのバリアントが期待されているかを必ず確認してください。
サイズオーバーヘッドが問題になる場面
Base64 は約 33% のサイズオーバーヘッドに加えて、わずかなパディングを足します。小さなペイロードでは無視できる量ですが、大きなファイルでは無視できなくなります。10 MB の画像を Base64 化すると約 13.3 MB のテキストになります。大きな画像をインラインの data URL にすると、本来の「リクエスト削減」の目的が薄れます。およそ 4–8 KB を超えるサイズでは、外部ファイル参照のほうがほぼ常に効率的です。
Base64 を使うべきでない場面
- バイナリをそのまま運べるトランスポートを使っている場合(HTTP ボディ、WebSocket バイナリフレーム、gRPC など)。
- 難読化や「簡易暗号化」のつもりで使う場合。
- 大きなファイルをインライン埋め込みする場合(オーバーヘッドとパースコストが利便性を上回ります)。
- デコーダーを持たない消費者に渡す場合(人間可読のログなど)。
デコード時の注意点
ほとんどの Base64 デコーダーはパディングと空白文字に厳密です。デコードエラーになった場合は、まず「=」パディングの欠落、MIME によって挿入された改行、URL セーフ/標準の取り違えを疑ってください。テスト時には、信頼できるデコーダー(本サイトの Base64 エンコーダー / デコーダーなど)に貼り付けて、どのエラーが出るかを確認するのが早いです。