記事
データをプライベートにエンコード・デコード
開発者は毎日、トークンやペイロード、認証情報をエンコード・デコードのページに貼り付けます。便利なものはサーバー上で動くため、本来必要のない作業のためにデータが端末から出ていきます。これら四つのツールは完全にブラウザー内で動くので、データはあなたの手元に残ります。
Base64:ごちゃごちゃに見えても秘密ではない
Base64は暗号化ではなくエンコードです。バイナリーデータを、コピー&ペーストや単純な文字しか扱えないシステムの通過に耐えるテキストへ変換します。Base64文字列を見た人は一手順で元へデコードできるため、APIキーや秘密鍵の証明書、メール本文を含む文字列は、それを持つ者には完全に読めてしまいます。危険なのは、その値が設定ファイルやデータURL、認証ヘッダーに紛れ込んで読みづらく見えることで、つい見つけた最初のオンラインデコーダーへ貼り付けたくなる点です。そのデコーダーは生の秘密を受け取ります。Base64をローカルでデコードするツールなら、値が一度もサーバーに届かないまま元のバイト列を表示できます。

URLエンコード:クエリ文字列は思った以上を運ぶ
パーセントエンコードは、空白やアクセント記号、予約文字を安全にURLへ入れられます。あなたがエンコードまたはデコードするテキストは、たいていアプリケーションの実際のクエリ文字列で、それらはセッション識別子、検索語、メールアドレス、リダイレクト先、ときには署名付きパラメーターを運びます。完全なURLをリモートのエンコーダーへ貼り付けると、それらすべてを一度に第三者へ渡すことになり、クエリ文字列はまさにサーバーログに残りやすい種類の値です。ブラウザーでエンコード・デコードするということは、URLが自分の端末のメモリー内で処理され、作業中に一度も送信されないということです。
JWT:ペイロードは署名されているだけで隠れていない
JSON Web Tokenはドットでつながれた三つのBase64urlの区画、すなわちヘッダー、ペイロード、署名から成ります。署名はトークンが改ざんされていないことを証明しますが、ペイロードを隠す働きは一切なく、ペイロードはユーザー識別子やロール、有効期限、発行者が追加した独自のクレームを含む読めるJSONへデコードされます。有効なトークンは生きた資格情報でもあり、失効するまでは、それを持つ誰もがそのユーザーとして振る舞えます。動くトークンをオンラインのデコーダーへ貼り付けると、自分が管理していないサーバーへ有効な資格情報を送ってしまいます。ブラウザー内でトークンを解析するデコーダーなら、そのトークンが一度もページを離れないまま、同じヘッダーとペイロードを表示します。

ハッシュ化:ダイジェストより入力が重要
ハッシュ関数は任意の入力を固定長のダイジェストに変えますが、ダイジェストから入力へ戻すことはできません。この性質のおかげで、ハッシュ化はファイルの完全性確認や、原本を保存せずに値を比較する用途に役立ちます。落とし穴は入力側にあります。パスワードや文書、設定上の秘密のハッシュを計算するには、本物の値をツールに与えねばなりません。そのツールがサーバー上で動く場合、返ってくるのは無害なダイジェストだけでも、機微な入力はそこへ送られます。ハッシュをローカルで計算すれば入力は端末内にとどまるので、ハッシュ化した対象を露わにせずに必要なダイジェストを得られます。
Base64エンコーディング:バイトマッピングとパディング
Base64は3バイトの入力(24ビット)を4つの6ビット値にグループ化することで、8ビットバイトを6ビット文字に変換します。各6ビット値はBase64アルファベット(A-Z、a-z、0-9、+、/)の文字にマッピングされます。このプロセスは24ビットで割り切れる入力を必要とするため、短い入力にはパディングが追加されます。残り1バイトの場合は2つのパディング文字(==)が、残り2バイトの場合は1つ(=)が付加されます。JSON Web Token(JWT)で使用されるBase64urlバリアントは、文字列をURLセーフにするために+を-に、/を_に置き換え、厳格なURIパーサーでエラーを起こす可能性があるため=パディングを完全に省略します。この区別はトークン処理のデバッグで重要です。不正な形式に見えるJWTは、単に標準Base64ではなくBase64urlでエンコードされているだけかもしれません。
JWTの署名:HS256、RS256、アルゴリズム混同攻撃
JSON Web Tokenのセキュリティは、ドットで区切られた第3セグメントである署名に全面的に依存しています。HS256(HMAC-SHA256)では、サーバーはBase64urlエンコードされたヘッダーとペイロードを秘密鍵を使用して署名します。SHA-256ハッシュ関数は衝突耐性を提供します。秘密鍵を知らずに、同じ署名にハッシュされる改ざんされたペイロードを生成することは計算上不可能です。RS256では、サーバーはRSA秘密鍵で署名し、公開鍵で検証します。アルゴリズム混同と呼ばれる既知の脆弱性は、サーバーライブラリが期待するアルゴリズムタイプを厳密に適用しない場合に生じます。攻撃者はトークンヘッダーのalgフィールドをRS256からHS256に変更し、公開鍵(多くの場合アクセス可能)をHMACの秘密として使用してトークンに署名できます。ブラウザ上でローカルにJWTヘッダーをデコードすることで、アクティブなトークンをサードパーティのログシステムに公開することなく、実際にどのアルゴリズムが指定されているかを確認できます。
この記事で紹介するツール
よくある質問
Base64やURLエンコードはセキュリティの一種ですか。
いいえ。どちらもデータを保護するためではなく、安全に運ぶために設計された可逆のエンコードです。エンコードされた文字列を読める者は、鍵もパスワードもなしに即座にデコードできます。値を秘密に保つ必要があるなら、適切なアルゴリズムで暗号化し、鍵を別に管理してください。Base64やパーセントエンコードのどんな値も、平文で書かれているものとして扱ってください。
トークンをどこでデコードするか、パスワードをどこでハッシュ化するかが、なぜ重要なのですか。
機微な部分が入力だからです。有効なJWTは生きた資格情報であり、ハッシュ化するパスワードは本物の秘密です。サーバー型のツールは結果を返す前に、その生の入力を受け取ります。つまり、複製がログに残ったり、あなたの見えない場所に保持されたりしかねません。ブラウザー内で動くツールは同じ処理を自分の端末のメモリー内で行うので、トークンやパスワードはどこへも送られません。