年表
| 年 | 文書 | 貢献した内容 |
|---|---|---|
| 1987 | RFC 989(PEM パート I) | = パディング付きの 64 文字による「printable encoding」と、暗号化しない部分を示す * |
| 1988、1989 | RFC 1040、RFC 1113 | PEM の改訂版ドラフト |
| 1992 | RFC 1341(MIME) | メールの Content-Transfer-Encoding としての Base64 |
| 1993 | RFC 1421(PEM)、RFC 1521(MIME) | ちょうど 64 文字の PEM の行、MIME の改訂 |
| 1996 | RFC 2045(MIME) | 現在も使われている MIME の定義:1 行最大 76 文字 |
| 1997 | RFC 2152(UTF-7) | Unicode 用テキストエンコーディング内での Base64 |
| 2003 | RFC 3501(IMAP4rev1) | メールボックス名用に , を使う修正 Base64 |
| 2003 | RFC 3548 | 初の単独仕様:base64、base64url、base32、base16 |
| 2006 | RFC 4648 | RFC 3548 を置き換え、base32hex とテストベクターを追加 |
| 2007 | RFC 4880(OpenPGP) | CRC-24 チェックサム付きの Radix-64 アーマー |
| 2015 | RFC 7468 | PEM 形式の証明書・鍵ファイルの厳密なルール |
| 2015 | RFC 7515(JWS) | トークン用のパディングなし Base64URL |
| 2024 | RFC 9580(OpenPGP) | RFC 4880 を置き換え、アーマーのチェックサムを非推奨に |
PEM:Base64 の始まり
現在使われているアルファベットが初めて登場したのは、1987 年 2 月に公開された RFC 989「Privacy Enhancement for Internet Electronic Mail」です。暗号化されたメールは印字可能なテキストしか扱えないゲートウェイを通過する必要があったため、PEM にはバイナリの暗号文を、どのメールシステムでも壊れない文字で書く方法が必要でした。そこで 6 ビットずつ取り出して A-Z、a-z、0-9、+、/ に割り当て、パディングには = を使いました。RFC 989 の表は、このサイトのアルファベット表とまったく同じです。暗号化されていない部分を示すために * も予約されていましたが、この機能は残りませんでした。
PEM は RFC 1040、RFC 1113 を経て RFC 1421(1993 年 2 月)に落ち着き、そこで行の長さが「最終行を除く各行はちょうど 64 文字の印字可能文字を含み、最終行は 64 文字以下とする」と固定されました。理由として挙げられたのは、印刷と SMTP の 1 行 1000 文字の制限です。セキュアメールの仕組みとしての PEM は普及しませんでしたが、そのファイル形式は生き残りました。-----BEGIN CERTIFICATE----- で始まるブロックはすべてその子孫で、現在は RFC 7468(2015 年)がルールを明文化しています。生成側はちょうど 64 文字で折り返さなければならず、解析側はそれ以外の幅を受け入れてもかまいません。こうしたファイルは証明書デコーダーで中身を確認できます。
MIME:すべてのメール添付ファイルに Base64
MIME(1992 年の RFC 1341、1993 年の RFC 1521、1996 年の RFC 2045)は、画像や文書をメールに入れる方法を必要としており、PEM のエンコーディングを借用しました。RFC 2045 は今でもメールの参照仕様で、PEM とは 2 点が異なります。
- エンコードされた各行は 76 文字を超えてはならず、CRLF で区切ります。
- 「base64 でエンコードされたデータ中の、base64 アルファベット以外の文字は無視する」。デコーダーは改行、空白、その他アルファベットに含まれない文字を読み飛ばします。
多くのデコーダーが無効な文字を黙って捨てるのは、この 2 つ目のルールのためです。MIME 形式の出力は MIME Base64 エンコーダーで生成できます。添付ファイルの構造についてはメールでの Base64 を参照してください。
RFC 3548 と RFC 4648:共通の参照仕様
2003 年までは、Base64 を使うプロトコルはどれも MIME か PEM を参照しており、望むと望まざるとにかかわらず、行の長さや寛容なデコードのルールまで引き継いでいました。RFC 3548(2003 年 7 月)は base64、base64url、base32、base16 を単独のエンコーディングとして定義しました。RFC 4648(2006 年 10 月)は小さな変更を加えてこれを置き換え、エンコード後もデータの並び順を保つ base32hex と、次のテストベクターを追加しました。
BASE64("") = ""
BASE64("f") = "Zg=="
BASE64("fo") = "Zm8="
BASE64("foo") = "Zm9v"
BASE64("foobar") = "Zm9vYmFy"
参照元の仕様が別途定めない限り、RFC 4648 のルールは MIME より厳格です。
- 改行:実装は改行を入れてはなりません(3.1 節)。
- パディング:実装は
=のパディングを付けなければなりません(3.2 節)。 - アルファベット以外の文字:デコーダーはこれを拒否しなければなりません(3.3 節)。
- 正規エンコーディング:エンコーダーは未使用のビットをゼロにしなければならず、デコーダーはそうなっていない入力を拒否してもかまいません(3.5 節)。このルールがなければ、
SGk/Pg==とSGk/Ph==はどちらもHi?>にデコードされます。
「この文書を参照する仕様が明示的に別段の定めをしない限り」という一文が大きな役割を果たしています。JWS がパディングを省略でき、MIME が 76 文字の行を維持できるのに、どちらも「RFC 4648 の Base64」を使っていると言えるのはこのためです。同じ RFC の残り 2 つのエンコーディングは、Base32 と Base16 のツールで扱えます。
他の規格で定義されたバリアント
JWS と JWT:パディングなしの Base64URL
RFC 7515(2015 年 5 月)は BASE64URL(x) を、5 章のアルファベットを使い「末尾の ‘=’ をすべて省略した」もので、改行や空白を含まないものと定義しています。JWT、JWE、JWK をはじめ、JOSE ファミリーのほとんどがこれを使います。詳しくは JWT での Base64 をご覧ください。
IMAP:カンマを使う修正 UTF-7
IMAP のメールボックス名は 7 ビットの文字列なので、RFC 3501(5.1.3 節)は ASCII 以外のフォルダー名を「修正 UTF-7」でエンコードします。連続する非 ASCII 文字を UTF-16 に変換し、/ の代わりに , を使ってパディングなしで Base64 エンコードし、& と - で囲みます。RFC 自身の例 &U,BTFw- は中国語の地名「台北」で、ドイツ語のフォルダー名 Entwürfe は Entw&APw-rfe になります。通常の UTF-7(RFC 2152)では、同じ名前は Entw+APw-rfe と書かれます。
OpenPGP:CRC-24 付きの Radix-64
OpenPGP の ASCII アーマーは、MIME の Base64 にチェックサム行を加えたものです。RFC 4880 はバイナリデータに対する CRC-24(生成多項式 0x864CFB、初期値 0xB704CE)を定義しており、これを Base64 エンコードして先頭に = を付けます。12 バイトの Hello world! に対して GnuPG が出力するのは次のとおりです。
-----BEGIN PGP ARMORED FILE-----
Comment: Use "gpg --dearmor" for unpacking
SGVsbG8gd29ybGQh
=s4Gu
-----END PGP ARMORED FILE-----
RFC 4880 は 1 行最大 76 文字を認めていますが、GnuPG は 64 文字で書きます。RFC 9580(2024 年 7 月)は形式を維持しつつ、CRC-24 の行は「生成すべきでない(SHOULD NOT)」とし、この行が欠けていたり誤っていたりしてもブロックを拒否してはならないとしています。
Base64 バリアントの一覧表
| バリアント | インデックス 62 と 63 | パディング | 行の長さ | 定義 |
|---|---|---|---|---|
| 標準 Base64 | + / | 必須 | なし | RFC 4648、4 章 |
| Base64URL | - _ | 任意(参照元の仕様による) | なし | RFC 4648、5 章 |
| JWS / JWT | - _ | 付けない | なし | RFC 7515 |
| MIME | + / | 必須 | 最大 76、CRLF | RFC 2045 |
| PEM | + / | 必須 | ちょうど 64 | RFC 1421、RFC 7468 |
| OpenPGP アーマー | + / | 必須 | 最大 76(GnuPG:64) | RFC 4880、RFC 9580 |
| UTF-7 | + / | なし | 該当なし | RFC 2152 |
| IMAP 修正 UTF-7 | + , | なし | 該当なし | RFC 3501 |
| bcrypt | アルファベット ./A-Za-z0-9 | なし | 該当なし | 事実上の標準(OpenBSD) |
| crypt(3) ハッシュ | アルファベット ./0-9A-Za-z | なし | 該当なし | 事実上の標準(Unix) |
最後の 2 行では、アルファベット全体の並びが変わっています。これらはアルファベットのページで扱っています。他の多くの形式は、上の表のいずれかを何も変えずに参照しています。HTTP Basic 認証(RFC 7617)、Data URI(RFC 2397)、XML Schema の base64Binary、Subresource Integrity のハッシュは、いずれもパディング付きの標準 Base64 を使います。
よくある質問
Base64 を定義している RFC はどれですか?
一般的な参照先は RFC 4648(2006 年 10 月)で、base64、base64url、base32、base32hex、base16 を定義しています。MIME 版は RFC 2045、PEM の原典は RFC 1421 にあります。
MIME の行が 76 文字、PEM の行が 64 文字なのはなぜですか?
どちらも SMTP の 1 行 1000 文字という制限を十分に下回るための値です。PEM は RFC 1421 で 64 文字に固定し、MIME は独自の仕様で「76 文字以下」と決めました。RFC 4648 は、参照元の規格が求めない限り、エンコーダーは改行を一切入れてはならないとしています。
Base64URL は正式な規格ですか?
はい。RFC 4648 の 5 章「Base 64 Encoding with URL and Filename Safe Alphabet」がそれで、最初に登場したのは RFC 3548 です。JWS(RFC 7515)はこれをパディングなしで使います。
PGP ブロックの末尾にある =XXXX という行は何ですか?
デコード後のデータに対する CRC-24 チェックサムで、それ自体も Base64 で書かれています。RFC 9580(2024 年)は、新しい実装はこれを出力すべきでなく、この行を理由にブロックを拒否してはならないと定めています。