Base64 説明: どのように動作し、いつ使うか、いつ使わないか
Base64のエンコーディングの明確な説明: アルゴリズム、パッディング、URL-セーフ Base64、データ URL、サイズオーバーヘッド、ユニコードの落とし穴、セキュリティに関する誤解。
· 7 分で読めます
メール添付ファイル、JSON Webトークン、データ URL、Kubernetesの秘密、HTTPBASIC認証、数え切れないほどのAPIでバイナリデータをテキストのみのチャネルで移動する必要があります。暗号化のように誤用されることが多いのです暗号化とは。この記事では、アルゴリズムのステップ・バイ・ステップ、一般的なバリエーション、そしてBase64が正しいツールであるときに実践的なガイドが説明されています。
Base64 で解決する問題
多くのシステムは任意のバイトではなくテキストを運ぶように設計されました。メール (SMTP) は、歴史的に7ビットASCIIのみをサポートしている。JSON 文字列は、raw バイナリ文字列を含めない。URLとHTTPヘッダには文字セットが制限されています。制御文字や行末や境界線として解釈されデータが破損します画像の原始バイトを
Base64は任意のバイトを 64 つの安全で印刷可能な文字にマップします。A–Z、a–z、0–9、+ と /。普通のテキストを運ぶシステムならデータも完ぺきに運べます
暗号化機能について
Base64は3バイト (24ビット) のグループで入力処理し、それぞれ6ビット4文字を出力する。2 ^ 6 = 64 のため、各6ビット値はアルファベットから1つの文字を選択します。
Manという言葉を
- ASCIIバイト:
M= 77、a= 97、n= 110 - バイナリでは
01001101 01100001 01101110 - 6ビットグループに分けます
010011 010110 000101 101110 - 数字として: 19、22、5、46。
T、W、F、uの順序をチェックしてください
Man は TWFu になります。解読はプロセスを逆転させる
敷き詰め =
入力長が 3 の倍数でないとき、最後のグループが不完全である。ベース64のパッド:
- 余った1バイトは2文字+
==になります - 3文字+
=を生成します。
MaはTWE=とMはTQ==にコード化される。パッディングは出力長を 4 の倍数にしますこれはいくつかの解読機が必要になります。他の実装では、特に URL 安全な実装では、長さがすでに何バイトが欠落しているかを意味しているため、省略されます。
オーバーヘッドのサイズ
3バイトごとに4文字になるので、Base64出力は入力より約33%大きく、パッディングと時には行切れ (MIMEメールは76文字で行を巻く)。1MBの画像は約1.37MBのテキストになります。JSONやHTMLで大きなファイルを埋め込むとき重要になります
URL 安全なBase64
標準アルファベットには、URLで特別な意味を持つ+と/と、クエリ文字列で使用される=が含まれています。RFC 4648 で定義されたBase64URLは、+ を - で、/ を _ で置き換え、通常はパッディングを落とす。JWTや多くの API トークンや Web プッシュキーは、この変種を使用しています.例として [JWT の動作方法] (/blog/how-jwt-works) をご覧ください。
-と_では標準的な解読機が失敗し、その逆もまた"無効文字"エラーの一般的な原因です。対応する [Base64デコーダー] ((/tools/base64) は、両方のアルファベットを受け入れ、欠落したパッディングを自動的に復元します。
テキスト、バイト、ユニコード
文字ではなくバイトを暗号化します。文字を暗号化するには、まず文字の暗号化でバイトに変換する必要があります。ほぼ常にUTF-8です。JavaScriptの内蔵btoa()は Latin-1範囲の文字しか受け入れませんだからbtoa("héllo")は偶然動作し btoa("你好")はエラーを投げ出します
現代のJavaScriptで正しいアプローチは:
const bytes = new TextEncoder().encode("你好 👋");
const b64 = btoa(String.fromCharCode(...bytes));
const back = new TextDecoder().decode(Uint8Array.from(atob(b64), c => c.charCodeAt(0)));
Pythonのbase64.b64encodeはバイトを要するので base64.b64encode("你好".encode("utf-8"))を書きます
データ URL
データ URL は HTML または CSS に直接ファイルを埋め込む:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="">
これは HTTP/1.1 時代には価値があった HTTP 要求を保存します。HTTP/2 マルチプレックスでは、通常は別々のファイルが優先されます。
- データ URL は独立してキャッシュすることはできません.それらを含むすべてのページまたはスタイルシートで再ダウンロードされます。
- HTMLとCSSを膨らませるのでダウンロードして解析するまでレンダリングができません
- gzip が一部を回復しても、33%のオーバーヘッドが適用されます。
12KB未満の小さなアイコン、スペースホルダー画像、または単一のファイル HTML エクスポートのためのデータ URL を使用します。For anything larger、serve a normal file and compress it instead。
Base64は暗号化ではありません
これが一番重要なポイントです。ベース64には鍵がない。誰でも即座に解読できますし多くのツールでは自動的に解読できます。しかしよく見られるのは
- データベース64で"隠された"APIキーです
- パスワードはデータベースやコンフィギュレーションファイルにベース64コードで保存されます
- Kubernetes Secrets は、その値がBase64であるため、保護されていると仮定します。
Kubernetes は、YAML に適合するバイナリデータのために、Base64 で秘密値をコードする.保護は、アクセス制御と静止状態の暗号化から生じる。データが機密である必要がある場合は、AES-GCMのような実際のアルゴリズムで暗号化し、パスワードを検証する必要がある場合は、パスワードハッシュ機能を使用します。
よくある使い方
- HTTP 基本認証は
Authorization: Basic base64(user:password)を送信します。暗号化によって特典文字の問題が回避され、認証情報は HTTPSのみで保護されます。 - メール添付ファイルは MIME Base64 を使用し、76 文字ごとに行を断ち切る。
- JSON**に小さな署名画像や暗号鍵などのバイナリを埋め込むことは合法的な使用です。大型ファイルについては別々にアップロードし、URLで参照してください。
- 環境変数で TLS 証明書などのテキストのみの設定でバイナリを格納する
デコードエラーのトラブルシューティング
- 無効文字: 標準的な解読機でBase64URLを解読している可能性があり、文字列には空白や行間があります。
- **誤ったパッディング:**長さが4の倍数になるまで
=を足す。 - **解読後にテキストが歪んだ:**オリジナルは異なる文字セットから暗号化された、またはデータはテキストではなくバイナリです。
- **出力は再びBase64のように見えます:**データは2回エンコードされ、もう一度解読されました。
関連コード
- Base32は32文字 (AZと27) を使用し、大文字に敏感でない.認証アプリのTOTP秘密で使用される。オーバーヘッドは60%です
- Hexadecimal (Base16) はバイト1つに2文字を使用します。100%オーバーヘッドです。
- Base58は類似した文字を削除し、ビットコインアドレスで使用されます。
- %エンコーディングは URL の不安全文字のみを回避します
まとめ
Base64 はバイトを 64 文字のテキストアルファベットに変換します。一度に 3 バイトで、約 33% の追加サイズで。テキストチャネルを通じてバイナリデータを転送するために使用します。URLとトークンで URL-セキュア変種を使用します.常にテキストを最初に UTF-8 バイトに変換します。秘密を守るために使うな暗号化だ鍵じゃない
このページは英語から自動翻訳されています。誤りを見つけた場合はお知らせください。