aGVsbG8gd29ybGQ=——こんな文字列を見たことはありませんか?これがBase64です。メール添付ファイル、Webサイトに埋め込まれた画像、JWT トークン、Basic認証ヘッダー……Webの裏側で日々使われているのに、いざ「何をしている処理なのか」と聞かれると答えづらいフォーマット、それがBase64です。
この記事では、Base64 が何をしているのか、なぜ必要なのか、どこで使われているのか、そして「Base64 は暗号化ではない」という最大の誤解について、まとめて整理します。
Base64とは — バイナリをテキストに変換する方法
Base64 は、バイナリデータ(画像・音声・実行ファイルなど、テキスト以外のすべて)を、64種類の印刷可能なASCII文字だけで表現するエンコード方式です。
なぜそんなことをするのか?答えは 「テキストしか通せない通り道がたくさんある」 からです。メールの本文、URLのパラメータ、JSON の文字列、HTML の属性値——これらはすべて「テキスト前提」の仕組みで、生のバイナリを入れると壊れたり拒否されたりします。
Base64 は、そういう経路にバイナリを安全に通すための「変換アダプタ」だと考えるとイメージしやすくなります。
なぜ「64」なのか — 文字テーブルの中身
Base64 で使われる64文字は次の組み合わせです。
A〜Z(26文字)a〜z(26文字)0〜9(10文字)+と/(2文字)
合計64文字。さらにパディング用の = が予備として使われます。
なぜちょうど64なのかというと、コンピュータの世界では 2の累乗 がとにかく扱いやすいからです。64 = 2の6乗。つまり、6ビット(0〜63 の数値)ひとかたまりに、ちょうど1文字を割り当てられます。8ビット(1バイト)と 6ビットの最小公倍数は 24(=3バイト=4文字)なので、3バイト→4文字の変換でぴったり収まる、というのが Base64 の中心の仕組みです。
変換の流れ — 3バイトずつ4文字へ
実際の変換手順は、次のとおりです。
- 元データを 3バイトずつ 区切る。
- 3バイト = 24ビットを、6ビットずつ4分割する。
- 各6ビットを 0〜63 の数値として扱い、対応する文字に置き換える。
- 余りが出た場合は
=でパディング。
試しに「ABC」を変換してみます。
- 「ABC」のASCIIコード:
0x41 0x42 0x43 - 2進数:
01000001 01000010 01000011 - 6ビットずつ:
010000 010100 001001 000011 - 10進数:
16 20 9 3 - テーブル変換:
Q U J D
結果:「ABC」→「QUJD」。たった3文字が4文字になりました。
サイズが約33%増える理由
変換すると、データ量が 元の約1.33倍(4/3倍)になります。これは「3バイト→4文字」の比率からそのまま導かれる結果です。
この増加は無視できないコストです。1MBの画像を Base64 にすると約1.33MB。HTTP で送るなら gzip 圧縮があるので実害は少なめですが、メモリ上に保持したり、データベースに入れたりすると、それなりに効いてきます。
パディング — 末尾の「=」の意味
元データが3の倍数でないとき、末尾を「3バイトの倍数」になるよう調整するため、出力に = が付きます。
- 元データが3の倍数:パディングなし
- 元データが3で割って 余り1バイト:末尾に
== - 元データが3で割って 余り2バイト:末尾に
=
だから aGVsbG8= のように = 1つや2つが末尾に付いている文字列は「あ、これはBase64だな」と一目で見分けられるサインになっています。
URLセーフBase64 — Web向けの変種
標準のBase64には + と / が含まれますが、これらはURLの中で特殊な意味を持つ文字です(URLエンコードが必要)。そこで、Web向けに URLセーフBase64 という変種が定義されました(RFC 4648 §5)。
+を-に置換/を_に置換- パディング
=を省略することも多い
JWT(JSON Web Token)のヘッダー・ペイロード・署名はすべてURLセーフBase64で書かれていて、これによりURLパラメータやHTTPヘッダーにそのまま乗せられるようになっています。
使われる場面 — 「これBase64だったの?」例
メール添付ファイル(MIME)
メールの本文はもともと7bitテキスト前提のプロトコル(SMTP)で送られていました。画像や添付ファイルを送るために、バイナリをBase64で包んで本文に埋め込む方式が確立されました。これがいまもメールの定番です。
HTML/CSS の Data URI
<img src="data:image/png;base64,iVBORw0KGgo..."> のように、画像をHTMLに直接埋め込めます。小さなアイコンや CSS の background-image でよく使われ、HTTPリクエスト数を減らす定番テクニックです。
JWT(JSON Web Token)
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.SflKxw... のような、ピリオドで3つに区切られた文字列。それぞれの部分はURLセーフBase64で書かれた JSON(ヘッダー・ペイロード)と署名です。
Basic認証
HTTPヘッダー Authorization: Basic dXNlcjpwYXNz の dXNlcjpwYXNz は user:pass をBase64化したもの。後述の通り、これは暗号化ではないので、HTTPS の上でしか使ってはいけません。
API レスポンスでのバイナリ
REST API は JSON 前提なので、画像などのバイナリを返したい時はBase64で包んで文字列フィールドに入れることがあります。
最大の誤解 — Base64は「暗号化」ではない
これだけは絶対に覚えてください。Base64は「人間が読めないように見える」だけで、誰でも一瞬で元に戻せるエンコードです。セキュリティ機能はゼロです。
以下のような使い方は危険です。
- パスワードを Base64 で「保護」したつもりになる:実際にはほぼ平文と同じ。攻撃者は数秒でデコードできる。
- Basic認証を HTTPS なしで使う:Base64 された認証情報がそのまま通信路を流れ、誰でも盗聴できる。
- 機密データを Base64 でメールに添付すれば安心:違う。中身は誰でも復号できる。
Base64 はあくまで「テキストしか通せない経路にバイナリを通すための形式変換」であって、機密保護とはまったく別の話です。本当に機密にしたいなら、AES等の暗号化や、PGP/GPG・S/MIMEのような署名暗号化を組み合わせる必要があります。
使うときのハマりどころ
- 改行が混じってデコードに失敗:メールの添付などは、76文字ごとに改行を入れる古い慣習がある。デコード側で改行除去が必要。
- 標準Base64とURLセーフBase64を取り違える:
+//vs-/_の違い。 デコーダー側のオプションをそろえる必要がある。 - パディングが落とされている:URLセーフではよく省略される。デコーダーが厳密だと失敗するので、自前で
=を補う処理が要ることがある。 - UTF-8 と二重エンコードの取り違え:日本語文字列をBase64化する時、UTF-8でバイト列にしてからBase64にするのが標準。Shift_JIS バイト列を渡すと、受け側で別の言語として復号されてしまう。
各言語での扱い方
Base64 はあらゆる言語に標準ライブラリがあります。
- JavaScript(ブラウザ):
btoa()(エンコード)/atob()(デコード)。ただし日本語を含む場合は事前に UTF-8 化する必要がある。btoa(unescape(encodeURIComponent(text)))が定番イディオム。 - Node.js:
Buffer.from(text).toString('base64')。UTF-8 は自動。 - Python:
base64.b64encode(b'hello')。URLセーフ版はurlsafe_b64encode。 - PHP:
base64_encode('hello')。
本サイトの Base64変換ツール なら、コーディング不要で文字列やバイナリのエンコード/デコードがブラウザ完結で試せます。日本語文字列の取り扱いもUTF-8で適切に行うので、変な文字化けは起きません。
関連する文字コード変換
Base64の他にも、用途別の「文字列の安全化」方式があります。
- URLエンコード(percent-encoding):
%E3%81%82のような形式。URLに日本語や特殊文字を含めるとき用。詳しくは URLエンコードツール へ。 - HTMLエンティティ:
&、<など。HTMLに < や & を表示するとき用。 - Hex(16進数):バイト列を
0123456789ABCDEFの16文字で表現。デバッグ表示やハッシュ値の表示でよく使う。
まとめ — 「テキスト経路にバイナリを通す変換アダプタ」
Base64 は、現代のWeb開発で意識せずに使っているけれど、いざ向き合うと意外と細かい仕様の固まりです。要点を3つに集約すると次のとおり。
- テキストしか通せない経路にバイナリを通すための「形式変換」(暗号化ではない)。
- 3バイト→4文字、サイズは約1.33倍、末尾は
=でパディング。 - Web向けにはURLセーフ版(
-/_)がある。JWTなどはこちら。
実務で迷ったら、まず本サイトの Base64変換ツール でエンコード/デコードを試して、目で見て理解するのが一番の近道です。