開発者ツール · UUID ジェネレーター
Math.random と crypto.getRandomValues: 各ジェネレーターの仕組み
· 仕組み
uuid 暗号化 ブラウザ API
どちらもランダムに見える数値を返しますが、1 つは小さな決定論的なステート マシンで、もう 1 つはオペレーティング システムによって供給されます。それぞれが内部で何を行うのか、そしてなぜ UUID が 2 番目を使用する必要があるのかを次に示します。
Math.random から UUID を構築するフォーラム スニペット — それが適切に見え、すべてのカジュアル テストに合格する理由
フォーラムの回答では、8 行で簡単な UUID ファクトリーを提供しています。Math.random から値をロールし、8-4-4-4-12 レイアウトにフォーマットします。コードは問題なく見え、すべてのカジュアルなテストに合格します。各識別子は異なって表示され、短いサンプルでは明らかな視覚的パターンは示されません。これは、セキュリティに敏感な識別子に必要なプロパティではありません。 JavaScript は Math.random を疑似ランダム ソースとして指定しますが、予測に対する暗号耐性は必要ありません。適切なジョブには、シミュレーション、ゲーム、シャッフルなどがあります。識別子がアクセス、オブジェクトの発見、またはその他の敵対的な決定に影響を与えると、外観は証拠ではなくなります。ジェネレーターの文書化された契約は、一見もっともらしい出力のページよりも重要です。
内部 Math.random — 秘密性ではなく、速度と統計的拡散を目的として設計された、内部状態が固定されたシードされた擬似乱数アルゴリズム
Math.random は暗号ジェネレーターとして指定されていないため、その出力を将来の値がオブザーバーから隠蔽されていることを示す証拠として扱ってはなりません。 crypto.getRandomValues には別のプラットフォーム コントラクトがあり、整数型の配列に暗号的に強力な値を埋め込みます。 Web 暗号化の仕様では、正確なジェネレーターはユーザー エージェントに委ねられているため、アプリケーション コードは特定のアルゴリズム、シード サイズ、またはエントロピー デバイスを要求すべきではありません。 ToolAcre にはサポートされている境界のみが必要です。ブラウザーは安全なランダム バイトを提供し、JavaScript は埋められた Uint8Array を受け取り、UUID コードはバージョン フィールドとバリアント フィールドを設定します。このステートメントは便利であり、内部実装が異なるブラウザ間で移植可能です。
出力を観察することで状態が明らかになる理由 — 小さな状態が値の連続を意味し、次の値を予測できる仕組み
アプリケーション コードは、JavaScript PRNG 状態を実装または公開するのではなく、getRandomValues から暗号的に強力な値を受け取ります。セキュリティの違いは実際のシステムに現れます。 Math.random から構築された識別子は、ネットワーク (または以前の UUID が表示されるシステム) を読み取る能力を持つ攻撃者が次の UUID を予測できるため、予測が結果をもたらす場合には適していません。 crypto.getRandomValues の v4 UUID は、それ自体では認証トークンではありません (有効期限、ハッシュ、レート制限は必要です) が、ジェネレーターは予測に抵抗するように設計されています。 ToolAcre は、安全なソースが存在しない場合、予測可能な式に黙ってダウングレードするのではなく、識別子の生成を拒否します。 Math.random は、主要なエンジンに微妙な配布バグを抱えて出荷されています。出力シーケンスは、秘密を保持する役割に必要な敵対的な予測不可能性を提供せずに、多様に見える可能性があります。
crypto.getRandomValues 内 — ブラウザはオペレーティング システムの CSPRNG を要求します。CSPRNG はハードウェアとシステムのエントロピーを混合し、予測不可能になるように設計されています。
エンジン固有のアルゴリズムとその統計的動作は変更される可能性があります。目視検査やカジュアルな配布テストでは、Math.random を暗号化ソースにアップグレードすることはできません。衝突計算では、指定された空間からの独立した出力も想定されます。ジェネレーターが状態を繰り返したり、間違ってシードされたり、決定論的なフィクスチャに置き換えられたりした場合、その仮定は失敗し、式は実装を説明できなくなります。どちらの API も、同様に不規則に見える文字列を生成できます。脅威モデルはそれらを分離します。予測に抵抗する必要がある値には crypto.getRandomValues が使用されますが、シミュレーションと非敵対的シャッフルには Math.random が使用される場合があります。この選択は、サンプル内の句読点や見かけの多様性ではなく、予測の結果に基づいて行われます。
実用的な例 — 各メソッドで同じ数の識別子を生成し、オブザーバーが推測できる内容を比較する
ToolAcre UUID ジェネレーターは、crypto.getRandomValues のみを使用します。予測可能な UUID のコストは、わずかに遅いジェネレーターのコストよりも常に高いため、Math.random は決して使用されません。暗号化の違いは、脅威モデルを通じて測定できます。 UUID を偽造したい攻撃者は、識別子を直接推測するか、乱数ジェネレーターを破壊する必要があります。直接の推測は、この記事で数値化された比較ではありません。支持されている結論は、Web Crypto は暗号化のランダム性を目的としているが、Math.random はそうではないということです。 CSPRNG と Math.random は異なるコントラクトを公開します。前者はセキュリティに配慮したランダム性を考慮して設計されていますが、後者にはそのような保証はありません。識別子に Math.random を使用するシステムは暗号化プロパティを失いました。セキュリティは、生成された UUID のシーケンスを秘密に保つことに依存します。 UUID が 1 つでもリークすると、将来の世代全体が危険にさらされます。
過去の配布バグ — エンジンが目に見えて不均一な出力を持つ Math.random 実装を出荷してきたことを思い出させます (定性的に説明)
アプリケーションが UUID をログ、データベース、またはバージョン管理履歴に保存する場合、漏洩はほぼ避けられません。 ToolAcre ライブラリは、crypto.getRandomValues の使用を強制し、安全なコンテキスト (HTTPS または localhost) が使用できない場合は UUID の生成を拒否します。この設計上の決定により、多くの手巻き実装で問題となっていた Math.random へのサイレント フォールバックが防止されます。 Node.js では、ライブラリは暗号モジュールを使用します。ブラウザでは、Web Crypto API を使用します。サポートされている両方のパスは、プラットフォームから暗号的に強力なランダム性を要求します。エンジン、デバイス、ワークロードによってタイミングが決定されるため、この実装ではパフォーマンスは保証されません。セキュリティ契約は識別子の決定的なプロパティです。業界標準が crypto.getRandomValues に落ち着いた理由は、UUID の誤用の短い歴史にあります。初期のシステムでは、システム時間、ネットワーク インターフェイス、およびハードウェア クロックを使用して識別子を生成していました。
これでカバーされないもの — シミュレーション用のジェネレーターの統計的品質。これは予測不可能性とは別の問題です。
時間ベース、ノードベース、ランダムな UUID バージョンは、さまざまな割り当て問題を解決します。以前のすべての設計に対する直線的な修復として提示されるべきではありません。バージョン 4 の場合、RFC 9562 はランダム フィールドを定義し、推測不可能性について別途議論します。したがって、Math.random から移行すると、テキストの UUID 形状を変更することなく、新しく生成された値の品質が変わります。既存の識別子はデータベースキーのままです。再生成すると参照が壊れてしまいます。新しい値では Web 暗号をすぐに使用できますが、認可では引き続き古いまたは新しいすべての UUID を許可の証明ではなく識別子として扱う必要があります。カットオフを文書化して、インシデント対応者が各集団を生成したジェネレーターを把握できるようにします。
要点: ジェネレーターは、外観ではなく、脅威によって選択してください。ToolAcre UUID ジェネレーターは、Math.random() ではなく、CSPRNG のみを使用します。
検証では、従来の (機密性に適さない) ID と新しい (CSPRNG に基づく) ID を区別する必要があります。ドキュメントには移行について記載する必要があります。 ToolAcre ジェネレーターは、crypto.getRandomValues UUID のみを生成します。他のソースからの識別子の検証や再生成は試みません。 ToolAcre ジェネレーターは、より弱いランダム ソースへのダウングレードを拒否することでベスト プラクティスを示します。 crypto.getRandomValues が使用できない場合、ツールは Math.random を黙って使用する代わりにエラーを報告します。この設計原則は、あらゆるセキュリティ クリティカルなシステムに当てはまります。弱いセキュリティ保証で静かに成功するのではなく、大声で失敗します。 「UUID の生成に失敗しました: 暗号化 API が利用できません」というメッセージが表示された開発者は、根本的な問題に対処する必要があります (HTTPS へのアップグレード、安全なコンテキストの修正、または適切なフォールバックの提供)。 Math.random から構築された UUID をサイレントに受信する開発者には、システムが侵害されている兆候はありません。 ToolAcre ライブラリは利便性よりも誠実さを優先します。