日本語

開発者ツール · Base64 エンコーダーおよびデコーダー

Base64 は暗号化ではありません: エンコードされたシークレットが誰でも読み取れる理由

· なぜそれが重要なのか

base64 セキュリティ エンコード

Base64 でエンコードされたテキストがキーなしで即座にデコードされ、平文のコンテンツが表示されます。
オリジナル ToolAcre ベクトル イラスト

Base64 は何も隠しません。文字列を持っている人は誰でも、キーを使わずに即座に解読できます。この投稿では、エンコード、暗号化、ハッシュの違いと、リポジトリ内で Base64 シークレットを見つけた場合の対処方法について説明します。

スクランブルされ、データベース パスワードにデコードされたように見える設定値 - 具体的な発見とそれがどのくらい早く元に戻るか

構成ファイル内で Base64 を見つけると、誤った安全感が生まれます。開発者は、dGlnZXJfZGF0YWJhc2VfYWRtaW4 のようなスクランブルされたシーケンスとして表示されるデータベース パスワードを発見し、それが暗号化されていると想定し、アプリケーション コードとともにリポジトリにコミットします。数週間後のセキュリティレビューにより、実際の平文: Tiger_database_admin が明らかになりました。

Base64 は何も隠しません。それは暗号化ではなくエンコードです。逆にされた同じパスワードは、キーも計算も遅延もなく、ブラウザ内で即座に生の状態に戻ります。この投稿では、そもそもエンコードが存在する理由、エンコードが暗号化やハッシュと根本的にどのように異なるのか、コミットされた履歴で Base64 シークレットを見つけたときに実際に何が起こるのかについて説明します。

エンコード、暗号化、ハッシュ: 3 つの異なるジョブ - それぞれが何を保証し、どれがキーを必要とするか

Base64 が保護のように見えるため、混乱が生じます。人間は dGlnZXJfZGF0YWJhc2VfYWRtaW4 を一目見て、tiger_database_admin を読み取ることはできません。デコーダを介して実行するまでは不明瞭に見えます。表面レベルの難読化はセキュリティのように思えますが、そうではありません。 Base64 は、テキストのみのチャネルを介して任意のバイナリ データを移動するという、別の問題を完全に解決するように設計されました。電子メール、古い Web フォーム、ライン プロトコル システムでは、生のバイトを伝送できませんでした。 Base64 はバイトを印刷可能な ASCII 文字に変換するため、データはそのままの状態でチャネルを通過できます。

データが到着すると、受信者はそれをデコードしてバイトに戻します。エンコードとデコードは同様に簡単です。キーもエントロピーも暗号ライブラリも必要ありません。エンコード、暗号化、ハッシュは 3 つの異なる目的を果たし、3 つの異なる保証を提供します。エンコーディングはデータを別の表現に変換し、特定のチャネルを通過したり、特定のコンテキストで使用したりできるようにします。 Base64、URL エンコーディング、16 進表現、さらに JSON のエスケープ引用符もすべてエンコーディングです。これらは誰でも元に戻すことができ、秘密鍵は必要ありません。

Base64 がそもそも存在する理由 — テキスト チャネルを介したバイトの安全な転送、機密性の保護はありません

目標は形式の互換性であり、機密性ではありません。対照的に、暗号化には、許可された当事者のみが知っているキーが必要です。正しい鍵を持っている人だけが暗号文を平文に戻すことができます。キーがなければ、メッセージは、それを攻撃するのに十分な洗練された誰かにとってさえ、不透明なままです。ハッシュは設計上一方向であり、パスワードの暗号化ハッシュを元に戻すことはまったくできません。パスワード自体を保存せずに、パスワードが保存されているハッシュと一致することを検証するために使用されます。

Base64: dGlnZXJfZGF0YWJhc2VfYWRtaW4 を含む、database-password という名前の Kubernetes シークレットは、実際にはシークレットではありません。 Base64 は、Kubernetes が保護ではなくストレージに使用するデフォルトのエンコードです。 YAML または etcd データベースにアクセスできる人は誰でも、数秒で値をデコードできます。起動スクリプト内の Base64 でエンコードされた API キーを含む環境変数も、同じ問題に直面します。 Authorization: Basicbase64_username:password をサーバーに送信する Basic 認証ヘッダーは、クライアントとサーバー間の任意のプロキシ、監視ツール、またはネットワーク オブザーバーによってデコードできます。

作業例: ブラウザーでの「シークレット」文字列のデコード — サーバーを介さない、貼り付け、デコード、平文

チャネルが HTTPS ではなく HTTP である場合、危険にさらされる可能性はさらに高くなります。これらの文脈における Base64 は危険なニシンです。実際の秘密は、回復可能な形式で保存または送信されることによって、すでに侵害されています。実際に実行された例によって問題が具体化されます。サードパーティ サービスの API キーが構成ファイルに YXBpa2V5XzEyMzQ1Njc4OTAx として表示されているとします。この文字列をブラウザの Base64 エンコーダとデコーダにコピーし、入力フィールドに貼り付けて、[デコード] をクリックします。

ツールは apikey_1234567890 を返します。これは、サーバーに接続したり、キーを必要としたり、認証を実行したりすることなく、ブラウザーで即座に発生しました。操作全体には 1 秒もかかりません。次に、これと同じキーが悪意のある攻撃者によってパブリック GitHub リポジトリで発見されたとします。彼らは、好みのツールを使用して同じように簡単にそれをデコードし、それを使用してサービスにアクセスします。文字列がリポジトリ内で隠蔽されたままであるか、ネットワーク上を移動しているか、アプリケーション ログに表示されているかどうかは、あらゆるプログラミング言語やこのようなブラウザ ツールで利用できる簡単な操作で明らかにできます。

この間違いが発生する場所 — Kubernetes Secret、.env ファイル、Basic 認証ヘッダー、およびモバイル アプリのリソース

Base64 は非常に一般的であるため、近接性による難読化と関連付けられるため、間違いはどこにでも現れます。開発者は Base64 でエンコードされたデータを見て、誰かがそれが重要だと考えたと推測し、その形式に秘密を残します。 API_KEY=VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0 を含む .env ファイルは、デコードに 1 回の操作が必要であるにもかかわらず、API_KEY=This は実際には秘密ではありませんが、若手エンジニアには安全であるように見えます。モバイル アプリケーションは、逆コンパイラーが抽出してデコードできるリソースに Base64 でエンコードされたトークンをバンドルします。データベースのバックアップには、保護されるものではなく、検索されることを目的としたフィールドに Base64 でエンコードされたパスワードが含まれています。

いずれの場合も、誰かがエンコードを暗号化と間違えて、読み取りに 1 つの余分な手順が必要な形式になっている平文の秘密のアーカイブを作成しました。 Base64 シークレットが発見されたときに何をすべきかはコンテキストによって異なります。

代わりに行うべきこと — シークレット マネージャー、保存時の実際の暗号化、およびすでにコミットされたもののローテーション

シークレットがトークン、API キー、またはパスワードであり、すでにバージョン管理にコミットされている場合は、侵害されたものとして扱います。それを取り消し、新しいものを生成し、使用されたすべての場所を更新します。後で新しいコミットでシークレットが削除されたとしても、履歴コミットはリポジトリの永続レコードの一部です。リポジトリ履歴にアクセスできる人なら誰でも見つけることができます。

Base64 でエンコードされた値のリポジトリを検索することは、現在では標準的な偵察戦術であるため、何かが Base64 であったという事実はそれが秘密であることにはなりません。進行中の操作では、シークレットを Base64 でエンコードして保護されていると想定しないでください。暗号化され、アクセス制御され、監査可能な値を保存するシークレット マネージャーを使用します。アプリケーション コードと構成には、シークレット自体ではなく、参照または派生のみを保存します。保存時の実際の暗号化とは、データが個別に保存されたキーで暗号化され、そのキーを持たない人には役に立たないことを意味します。

これでカバーされない内容 — 暗号化アルゴリズムまたはキー管理設計の選択

機密列を暗号化するデータベース、ハードウェア セキュリティ モジュールのキーを使用してエンベロープ暗号化を使用するシークレット マネージャー、またはユーザー パスワードから暗号キーを導出するパスワード マネージャーはすべて、真の機密性を提供します。シークレットがどこかに保存される前に、シークレットが作成された時点でのアプリケーション レベルの暗号化はさらに強力です。たとえ Base64 でエンコードされたものであっても、公開されたシークレットをローテーションすることで、悪用の機会がなくなります。シークレットがリポジトリにある場合は、ログをチェックして、いつアクセスされたか、公開期間中に何に使用されたかを確認します。

継続的なセキュリティのためには、構成に保存されている静的なシークレットではなく、認可サービスによって発行された有効期間の短いトークンを使用してください。 1 時間で期限切れになるトークンは、侵害されたとしても攻撃者にとって価値が低くなります。この記事では、暗号化アルゴリズム、キー管理設計、認証アーキテクチャの選択については説明しません。これらは、独自の基準とトレードオフを伴う、より深いエンジニアリングの問題です。要点はもっと単純です。Base64 はこれらの問題を解決するツールの 1 つではありません。これは、転送および保存のためのフォーマット変換です。

要点: Base64 を平文として扱う — Base64 エンコーダーとデコーダーがタブから秘密を漏らすことなく、ワンクリックで要点を特定する方法

リポジトリ、構成ファイル、またはログに Base64 が表示されるからといって、データが保護されていると安心しないでください。テキストを読み取ることができるツールはいずれも Base64 をデコードでき、操作は即時かつ決定的です。 Base64 でエンコードされた文字列を暗号文として読み取ることはよくある誤解であり、本当の秘密が明らかになってしまいます。開発者は多くの場合、運用環境または監査で Base64 シークレットを見つけた後に初めてこれに気づきます。エンジニアがサンプル文字列をローカルでデコードし、元の平文が即座に表示されるのを確認すると、新しい視点が得られます。

このツールでは、エンコードは暗号化ではないという点が避けられません。この区別が明確になれば、フォローアップは自動的に行われます。コードベース内のすべての Base64 シークレットをローテーションする必要があります。シークレットが使用されるすべての場所を更新する必要があります。露出ウィンドウを評価する必要があります。将来的には、この役割のエンコーディングをシークレット マネージャーと実際の暗号化に置き換える必要があります。 Base64 エンコーダーとデコーダーは、秘密がブラウザーから離れることなく、逆転がいかに速くて簡単であるかを正確に示します。その容易さを実際のセキュリティ体制として扱います。1 秒で解読できるのであれば、他の誰でも解読できます。