Base64 を Base32 に変換する方法
- 入力 · Base64 に Base64 を貼り付けます。URLセーフの文字(
-、_)、パディングの欠落、改行があっても問題ありません。 - 出力 · Base32(RFC 4648) で結果を確認します。
otpauth://リンクや認証アプリに使う場合は、出力の下にある パディング(=) のチェックを外します。- 出力をコピー をクリックします。方向の切り替えで Base32(RFC 4648) → Base64 を選ぶと逆方向に変換できます。Base32 を Base64 に変換 のページでも同じことができます。
途中のバイト列は変わりません。20 バイトの鍵を入れれば 20 バイトの鍵が出てくることは、ツールの下の バイト カウンターで確認できます。
例
| Base64 | Base32 | バイト数 |
|---|---|---|
iEwO+V01Llzjb4MxBUtgEuCNW8o= | RBGA56K5GUXFZY3PQMYQKS3ACLQI2W6K | 20 |
iEwO-V01Llzjb4MxBUtgEuCNW8o | RBGA56K5GUXFZY3PQMYQKS3ACLQI2W6K | 20、URLセーフでパディングなしの入力 |
MTIzNDU2Nzg5MDEyMzQ1Njc4OTA= | GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ | 20、RFC 6238 のテスト用シークレット |
SGVsbG8h3q2+7w== | JBSWY3DPEHPK3PXP | 10 |
最初の行の 2 つの文字列はまったく似ていませんが、それで正常です。Base64 は 1 文字あたり 6 ビット、Base32 は 5 ビットを使うので、文字の並びが揃うことはありません。
避けるべき間違いは、Base64 の文字をテキストとしてエンコードしてしまうことです。iEwO+V01Llzjb4MxBUtgEuCNW8o= をテキスト用の Base32 エンコーダーに貼り付けると NFCXOTZLKYYDCTDM… が得られますが、これはその 28 文字そのものを表す有効な Base32 です。そこから生成される認証コードは、サーバーと一致することはありません。
Base64 のシークレットから TOTP を設定する
サーバー側のコードは、共有シークレットを Base64 で保存していたり、次のようなコマンドで生成していたりすることがよくあります。
openssl rand -base64 20
認証アプリに登録するには、ここで変換してからキー URI を組み立てます。
otpauth://totp/Example:alice@example.com?secret=RBGA56K5GUXFZY3PQMYQKS3ACLQI2W6K&issuer=Example
algorithm、digits、period はパラメータとして追加できます。指定がなければ、アプリは SHA-1、6 桁、30 秒とみなします。リンクはローカルの QR ツールで QR コードにするか、利用者に Base32 のシークレットを手入力してもらってください。シークレットはサーバーが HMAC に渡すのと同じバイト列なので、サーバーを変更しなくてもコードは一致します。
既存のものではなく新しいシークレットが必要な場合は、ランダム Base64 ジェネレーター(カスタムプリセット)で 20 バイトの乱数を Base64 として生成し、ここで変換してください。
一般的な鍵サイズでの長さ
| 鍵 | Base64 | Base32(パディングなし) | Base32(= 付き) |
|---|---|---|---|
| 10 バイト(80 ビット) | 16 | 16 | 16 |
| 16 バイト(128 ビット) | 24 | 26 | 32 |
| 20 バイト(160 ビット) | 28 | 32 | 32 |
| 32 バイト(256 ビット) | 44 | 52 | 56 |
10 や 20 のように 5 バイトの倍数のサイズでは、Base32 にパディングがまったく付きません。
Python での同じ変換
import base64
secret_b64 = "iEwO+V01Llzjb4MxBUtgEuCNW8o="
base64.b32encode(base64.b64decode(secret_b64)).decode().rstrip("=")
# 'RBGA56K5GUXFZY3PQMYQKS3ACLQI2W6K'
URLセーフな入力には base64.urlsafe_b64decode を使い、= パディングが削られている場合は先に補ってください。詳しくは Python での Base64 を参照してください。
よくある質問
認証アプリが Base64 ではなく Base32 を必要とするのはなぜですか?
アプリが QR コードから読み取る otpauth:// のキー URI 形式で、シークレットが Base32 と定められているからです。QR コードを読み取れないときに手入力できる必要もあり、Base32 には打ち間違えやすい +、/、大文字小文字の混在がありません。
Base32 のシークレットに = パディングは必要ですか?
otpauth:// リンクでは不要です。キー URI 形式ではパディングを省略すべきとされています。パディング(=) のチェックを外してください。20 バイトのシークレットは 32 文字なので、もともとパディングは付きません。
TOTP のシークレットはどのくらいの長さにすべきですか?
RFC 4226 は 128 ビット以上を必須とし、160 ビットを推奨しています。160 ビットは 20 バイトで、Base64 なら 28 文字、Base32 なら 32 文字です。
シークレットを Base32 に変換するとセキュリティ上のリスクはありますか?
エンコードは保護を加えることも取り除くこともありません。どちらの形式でも、文字列を持っている人なら誰でもコードを生成できます。リスクは貼り付ける場所にあります。このページはブラウザ内で変換し、Content Security Policy が Cloudflare のページビュー計測以外のネットワークリクエストをブロックしています。