開発者ツール · UUID ジェネレーター
HTTP ページで crypto.randomUUID() が失敗する理由: 安全なコンテキストの説明
· 仕組み
uuid 暗号化 ブラウザ API
crypto.randomUUID はローカルホストと HTTPS で動作しますが、プレーン HTTP ステージング ホストでは消えます。この投稿では、その動作の背後にあるセキュア コンテキスト ルールと、それが適用される場所で UUID を安全に生成する方法について説明します。
ステージングでは TypeError が発生するが、それ以外の場合は正常 — 症状とそれを引き起こす環境の違い
開発者が localhost:3000 での作業をチェックすると、UUID ジェネレーターは完全に動作します。これらは内部の http://staging. のステージングにデプロイされます。例。 com (社内 LAN 上のプレーン HTTP) にアクセスすると、コードは TypeError: crypto.randomUUID は関数ではありません をスローします。 https://example. com の実稼働環境の同じコードは正常に動作します。 MDN ドキュメントを読むまでは、この矛盾に困惑するでしょう。crypto.randomUUID は安全なコンテキストに制限されています。セキュア コンテキストは HTTPS または localhost のいずれかです。 LAN 上のプレーン HTTP オリジンは、ネットワークがプライベートであっても、ブラウザー ルールによって安全ではありません。修正するには、手動ビット操作で crypto.getRandomValues を使用するか、ステージング サーバーを HTTPS にアップグレードします。セキュア コンテキスト ルールは、機密性の高い API が暗号化されていない接続に漏洩するのを防ぐために導入されました。
セキュア コンテキストとは — HTTPS オリジンおよびローカルホスト用に特定の API を予約するブラウザー ルール
プレーン HTTP 上のページは、ネットワーク攻撃者によって傍受される可能性があります。このようなページに暗号化 API を公開すると、攻撃者が侵害された API を使用して識別子を生成することが可能になります。 HTTPS はページとすべての API 通信を暗号化するため、ネットワーク上の攻撃者がコードを傍受したり変更したりすることができません。 Localhost はローカル マシン上にのみ存在し、ネットワーク経由で傍受できないため、本質的に安全なものとして扱われます。その他の HTTP オリジン (LAN アドレス、HTTPS を使用しないパブリック ドメイン、HTTP に転送するリバース プロキシ) は、定義上安全ではありません。 Web Crypto API は、セキュア コンテキストに限定される crypto.randomUUID と、セキュア コンテキストと非セキュア コンテキストの両方で使用できる crypto.getRandomValues の 2 つの関数に分かれています。どちらも同じオペレーティング システム CSPRNG を使用します。
Web Crypto のどの部分がゲートされているか — crypto.randomUUID と crypto.subtle には安全なコンテキストが必要ですが、crypto.getRandomValues には必要ありません
違いは、getRandomValues は暗号化を使用しているという事実を隠さないことです。これを使用するページはランダムなバイトを明示的に要求する必要があります。 randomUUID 関数は、安全なコンテキストを強制する便利な機能です。アプリケーションが安全でないページで UUID を生成する必要がある場合は、getRandomValues を使用し、バージョンとバリアント ビットを手動で設定する必要があります。 RFC 9562 はビット操作を指定します。 set byte 6 to (byte6 & 0x0f) |バージョン 4 の場合は 0x40、バイト 8 は (byte8 & 0x3f) | RFC バリアントの場合は 0x80。 ToolAcre ライブラリは、randomUUID が利用できない場合のフォールバックとして、まさにこれを実行します。失敗の再現: 潜在的に信頼できるものとして扱われないプレーンな HTTP オリジンから単純なページを提供します。 randomUUID が公開されているかどうかを確認し、Web Crypto リファレンスで安全でないコンテキストで許可されている getRandomValues を比較します。
getRandomValues から v4 UUID を構築する — RandomUUID が見つからない場合に CSPRNG を維持するマスキングとフォーマットのフォールバック
HTTPS 経由で提供されるファイル内の同じコードにより、randomUUID が公開される可能性があります。運用環境が「randomUUID は関数ではありません」と報告した場合は、まずオリジンがセキュア コンテキストであるかどうかを検査し、次にブラウザのサポートと別のスクリプトが暗号オブジェクトを置き換えていないかどうかを確認します。解決策は、HTTPS または UUID ビットを明示的に設定する getRandomValues 実装である可能性があります。 Math.random ポリフィルは同等のフォールバックではありません。暗号ソース コントラクトを削除しながら形状を再現します。ダッシュとバージョン番号のみをアサートするテストではその置換が見逃されるため、ソース パスと結果の文字列を確認してください。
動作した例 — http:// オリジンで障害を再現し、修正を確認する
しかし、識別子は予測可能になりました。攻撃者はシステムからいくつかの UUID をキャプチャすると、次の UUID を予測できます。アプリケーションがそのような識別子を誤ってベアラー資格情報として扱った場合、予測可能性は表面上の欠陥ではなく認可の失敗になります。正しい戦略は、サーバーを HTTPS にアップグレードするか (認証や機密データを含むページにとって常に正しい措置です)、明示的なビット操作で getRandomValues を使用することです (より多くのコードが必要ですが、暗号的には安全です)。安全なコンテキストはブラウザによって強制されます。構成変数や環境変数を使用してこれを回避することはできません。 ToolAcre ジェネレーターは HTTPS 経由でデプロイされるため、crypto.randomUUID が利用可能です。ツールで UUID を生成すると、randomUUID (セキュア コンテキスト チェックに合格した場合) またはビット操作で getRandomValues (プレーン HTTP を使用している場合、これはまれですが) が使用されます。
Math.random でポリフィルをすべきではない理由 — 魅力的なショートカットとそれに伴うセキュリティ コスト
どちらのパスも Math.random には戻りません。独自の UUID ジェネレーターを構築し、安全でないオリジンをターゲットにしている場合は、getRandomValues を使用してビット操作を自分で実行します。 HTTPS と localhost の両方でテストして、randomUUID が機能することを確認してから、http:// オリジンでテストして、getRandomValues フォールバックが正しいことを確認します。セキュア コンテキストの制限を理解すると、展開戦略を設計するのに役立ちます。アプリケーションを HTTPS を使用しないプライベート LAN (レガシー インフラストラクチャ、組み込みシステム) で実行する必要がある場合は、getRandomValues フォールバックが将来のパスとなります。選択できる場合は、どこでも HTTPS にアップグレードしてください。 Let's Encrypt を使用すると無料で、投資はアプリケーション全体のセキュリティに回収されます。 localhost での開発には制限がないため、運用環境にデプロイする前に、localhost と HTTPS ステージングで UUID ジェネレーターをテストしてください。本番環境では常に HTTPS を使用する必要があります。
これでカバーされないもの — セキュア コンテキスト ルールなしで API を公開する Node.js や Deno などのサーバー ランタイム
この制限はバグや迷惑ではありません。これは、事故を防止し、暗号化について考える必要があるセキュリティ機能です。より広範なパターンは、Web 暗号化 API が安全なコンテキストによってゲートされるというものです。 crypto.getRandomValues、暗号。微妙。暗号化、暗号化。微妙。 generateKey、およびその他すべての機密性の高い操作には、HTTPS または localhost が必要です。例外も上書きも、チェックを無効にする方法もありません。安全でないページが 1 つあると、ユーザーに対するセキュリティの保証が破られます。特定のページでのみ暗号化 API を使用するように注意している場合でも、間違い (または UUID ジェネレーターを含む依存関係) により、暗号化されていないページにランダム性の生成が漏洩する可能性があります。 ToolAcre ジェネレーターはこれをコード レベルで強制します。randomUUID が利用できない場合 (安全でないコンテキスト)、getRandomValues が使用されます。getRandomValues は利用可能ですが、異常なことが起こっていることをコード レビュー担当者に警告します。
要点: ジェネレーターではなくオリジンを修正してください — ToolAcre は HTTPS 経由で提供されるため、そのジェネレーターは設計により安全なコンテキストで実行されます
さらに良いことに、セキュア コンテキストが本当に利用できない場合 (getRandomValues も利用できない環境では、これはまれですが、古いシステムや組み込みシステムでは発生する可能性があります)、識別子の生成を拒否します。安全な暗号化 API をサポートするために既存のシステムを HTTPS に移行するのは一般的なプロジェクトです。 UUID が生成されるオリジン (認証サーバー、API バックエンド、またはキー アプリケーション サービス) から始めます。 TLS 証明書を取得します (Let's Encrypt が無料で提供します)。デフォルトで HTTPS を提供し、HTTP リクエストを HTTPS にリダイレクトするように Web サーバーを構成します。複数のブラウザと API クライアントを使用してテストし、すべてが機能することを確認します。次に、暗号化されていないページで呼び出される可能性のある残りの暗号 API がないかコードを監査し、修正します。 ToolAcre ジェネレーターは HTTPS を前提としています。それを使用している場合は、すでにそこへの道の一部になっています。