Base64
バイナリデータを ASCII テキストに変換するエンコーディング方式で、メールや JSON でのバイナリ転送に使われる
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.xxxxx
↑ Base64url(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 パラメータ |
実務での活用方法は関連書籍にも詳しい。