Base64

バイナリデータを ASCII テキストに変換するエンコーディング方式で、メールや JSON でのバイナリ転送に使われる

データ形式Web

Base64 とは

Base64 は、バイナリデータを 64 種類の ASCII 文字 (A-Z, a-z, 0-9, +, /) で表現するエンコーディング方式である。RFC 4648 で標準化されている。暗号化ではなく、単なるエンコーディングであり、誰でもデコードできる。

テキストしか扱えないプロトコル (メール、JSON、XML) でバイナリデータ (画像、ファイル、暗号鍵) を転送するために使われる。

エンコーディングの仕組み

3 バイト (24 ビット) のバイナリデータを 4 文字 (各 6 ビット) の ASCII テキストに変換する。

入力: "Hi" (0x48 0x69)
バイナリ: 01001000 01101001
6ビットずつ分割: 010010 000110 1001(00) ← 末尾をゼロ埋め
Base64文字: S      G      k      =   ← パディング
結果: "SGk="

3 バイトの倍数でない場合、末尾に = (パディング) が付く。

// Node.js
Buffer.from('Hello, World!').toString('base64');  // "SGVsbG8sIFdvcmxkIQ=="
Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString(); // "Hello, World!"

// ブラウザ
btoa('Hello, World!');  // "SGVsbG8sIFdvcmxkIQ=="
atob('SGVsbG8sIFdvcmxkIQ==');  // "Hello, World!"

サイズの増加

Base64 エンコードするとデータサイズが約 33% 増加する (3 バイト → 4 文字)。1MB の画像は Base64 で約 1.33MB になる。大きなファイルの転送には不向きで、S3 の署名付き URL や multipart upload を使う方が効率的だ。

実務での使われ方

JWT のペイロード

JWT のヘッダーとペイロードは Base64url (URL セーフな Base64) でエンコードされている。+-/_ に置換し、パディングの = を省略する。

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIxMjMifQ.xxxxxBase64url(header)    ↑ Base64url(payload)

API Gateway のバイナリレスポンス

API Gateway で画像や PDF を返す場合、Lambda のレスポンスボディを Base64 エンコードし、isBase64Encoded: true を設定する。

return {
  statusCode: 200,
  headers: { 'Content-Type': 'image/png' },
  body: imageBuffer.toString('base64'),
  isBase64Encoded: true,
};

Kubernetes の Secret

Kubernetes の Secret の値は Base64 エンコードで保存される。暗号化ではないため、echo 'cGFzc3dvcmQ=' | base64 -d で簡単にデコードできる。

Data URI

小さな画像を HTML/CSS に直接埋め込む。HTTP リクエスト数を削減できるが、キャッシュが効かないため大きな画像には不向き。

<img src="data:image/png;base64,iVBORw0KGgo..." />

Base64 は暗号化ではない

最も重要な注意点。Base64 は可逆的なエンコーディングであり、セキュリティ上の保護は一切提供しない。パスワードや API キーを Base64 エンコードして「暗号化した」と考えるのは危険な誤解だ。

エンコーディングの比較

方式 サイズ増加 用途
Base64 +33% メール, JWT
Base64url +33% URL, ファイル名
Hex +100% ハッシュ値
URL エンコード 可変 URL パラメータ

実務での活用方法は関連書籍にも詳しい。

関連用語