ファイルを選択
  1. base64hub
  2. Base64 を学ぶ
  3. Base64 の規格と RFC
リファレンス

Base64 の規格:PEM・MIME から RFC 4648 まで

Base64 には一人の発明者も、唯一の仕様書もありません。1987 年のセキュアメールから生まれ、MIME に採用され、2003 年にようやく単独の仕様として文書化されました。Base64 を定義している文書と、そこから生まれたバリアントを紹介します。

年表

年文書貢献した内容
1987RFC 989(PEM パート I)= パディング付きの 64 文字による「printable encoding」と、暗号化しない部分を示す *
1988、1989RFC 1040、RFC 1113PEM の改訂版ドラフト
1992RFC 1341(MIME)メールの Content-Transfer-Encoding としての Base64
1993RFC 1421(PEM)、RFC 1521(MIME)ちょうど 64 文字の PEM の行、MIME の改訂
1996RFC 2045(MIME)現在も使われている MIME の定義:1 行最大 76 文字
1997RFC 2152(UTF-7)Unicode 用テキストエンコーディング内での Base64
2003RFC 3501(IMAP4rev1)メールボックス名用に , を使う修正 Base64
2003RFC 3548初の単独仕様:base64、base64url、base32、base16
2006RFC 4648RFC 3548 を置き換え、base32hex とテストベクターを追加
2007RFC 4880(OpenPGP)CRC-24 チェックサム付きの Radix-64 アーマー
2015RFC 7468PEM 形式の証明書・鍵ファイルの厳密なルール
2015RFC 7515(JWS)トークン用のパディングなし Base64URL
2024RFC 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、CRLFRFC 2045
PEM+ /必須ちょうど 64RFC 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 年)は、新しい実装はこれを出力すべきでなく、この行を理由にブロックを拒否してはならないと定めています。

続けて読む