CryptGenRandomは、 Microsoft CryptoAPIに含まれる、暗号的に安全な擬似乱数生成関数であり、非推奨となっています[1] 。Win32 プログラムでは、乱数生成が必要なあらゆる場面でこの関数の使用をMicrosoftは推奨しています。2007年にヘブライ大学が発表した論文では、Windows 2000におけるCryptGenRandomの実装にセキュリティ上の問題があることが示唆されています(攻撃者がマシンを制御している場合)。Microsoftは後に、 Windows XPでは同じ問題が存在するものの、Vistaでは存在しないことを認めました。Microsoftは2008年半ばにWindows XP Service Pack 3でこのバグの修正プログラムをリリースしました[2] 。
Win32 API には 、Windows アプリケーションで使用するために Microsoft が提供する暗号化プリミティブのセットであるMicrosoft CryptoAPIによる包括的な暗号化サポートが含まれています。TLSサポート(Schannel API 経由)やコード署名などの Windows テクノロジはこれらのプリミティブに依存しており、これらのプリミティブは暗号的に安全な擬似乱数生成器(CSPRNG) に依存しています。は、Microsoft CryptoAPI に付属する標準の CSPRNG です。
CryptGenRandom
マイクロソフトが提供する暗号化プロバイダは、現在と呼ばれる内部関数CryptGenRandomに基づくの同じ実装を共有しています。[3] 2007 年の時点では、アルゴリズムの概要のみが公開されていました。
RtlGenRandom[アップデート]
[ RtlGenRandom ] は、 FIPS 186-2 付録 3.1の規定に従い、 SHA-1をG 関数として用いてランダムランダムを生成します。エントロピーは以下のとおりです。
- 現在のプロセス ID (GetCurrentProcessID)。
- 現在のスレッド ID (GetCurrentThreadID)。
- 起動時からのティックカウント (GetTickCount)。
- 現在の時刻 (GetLocalTime)。
- さまざまな高精度パフォーマンス カウンター (QueryPerformanceCounter)。
- ユーザー名、コンピューター名、検索パスを含む、ユーザーの環境ブロックのMD4ハッシュ。 [...]
- RDTSC、RDMSR、RDPMCなどの高精度内部CPUカウンタ
[省略: 低レベルのシステム情報フィールドとパフォーマンスカウンタの長いリスト] [4]
マイクロソフトは、2019年に公開されたホワイトペーパーで、Windows 10の乱数ジェネレータの実装について詳しく説明しています。[5] Windows 10では、
CryptGenRandom)はRtlGenRandom、最終的には に落ち着くProcessPrng。 は、プロセスのプロセッサごとのPRNGからバイト列を返す。PRNGは常に、FIPS SP800-90で規定されているAES-CTR-DRBGアルゴリズムを使用する。 は下位互換性BCryptGenRandomのために古いアルゴリズムの要求も受け入れるが、プロセッサごとのPRNGから乱数のみを返す。[5] : 8
暗号システムのCSPRNGのセキュリティは、動的な鍵マテリアルの源となるため、極めて重要です。HTTPS接続を保護するTLSセッションキーなど、「オンザフライ」で必要な鍵は、CSPRNGから生成されます。これらの擬似乱数が予測可能であれば、セッションキーも予測可能になります。CSPRNGはWin32環境における事実上の標準であるため、Windowsユーザーにとってそのセキュリティは非常に重要です。
CryptGenRandom
2007年11月にレオ・ドルレンドルフらがエルサレム・ヘブライ大学とハイファ大学で発表したCryptGenRandomの暗号解析では、Windows 2000のアルゴリズム実装に重大な脆弱性が発見されました。 [7]
この脆弱性を悪用するには、攻撃者はまず乱数生成器を実行しているプログラムを侵害する必要があります。論文で指摘されている弱点はすべて、攻撃者が生成器から状態ビットを盗み出すことに依存しています。この攻撃を実行できる立場にある攻撃者は、通常、あらゆる乱数生成器を無効化できる立場にあります(例えば、生成器の出力を盗聴したり、メモリ内で既知の値に固定したりするなど)。しかし、ヘブライ大学のチームは、攻撃者がCryptGenRandomインスタンスのセキュリティを永続的に侵害するには、状態ビットを一度盗むだけで十分だと指摘しています。また、収集した情報を使用して過去に生成された乱数を特定し、既に送信済みのクレジットカード番号などの情報を侵害する可能性もあります。
この論文の攻撃は、CryptGenRandom がストリーム暗号RC4 を使用しており、状態が分かれば逆方向に実行できるという事実に基づいています。また、CryptGenRandom がユーザー モードで実行されるという事実も利用しており、たとえばバッファー オーバーフローを悪用してオペレーティング システムへのユーザー レベルでのアクセス権を持つ人は誰でも、そのプロセスの CryptGenRandom の状態情報を取得できます。最後に、CryptGenRandom はエントロピーからシードを頻繁に更新しません。この問題は、各 Win32 プロセスが独自の CryptGenRandom 状態のインスタンスを持っているという事実によって悪化します。つまり、1 つのプロセスが侵害されても他のすべてのプロセスが推移的に侵害されるわけではありませんが、侵入に成功した場合の存続期間が長くなる可能性があります。
CryptGenRandomアルゴリズムの詳細は当時公開されていなかったため、ドルレンドルフのチームはリバースエンジニアリングツールを用いてアルゴリズムの仕組みを解明しました。彼らの論文は、Windowsの暗号乱数生成器の動作に関する初の公開記録です[要出典]。
Windows 2000、XP、2003はすべて、CryptGenRandom()およびFIPSGenRandom()の実装を含め、EAL4+の評価に合格しています。セキュリティターゲットに関するドキュメントはCommon Criteria Portalで公開されており、EAL4要件への準拠を示しています。そのため、アルゴリズムのセキュリティについて結論を導くことはほとんどできません。EAL4は、ベストプラクティスや明示されたセキュリティ目標に照らして製品を評価しますが、詳細な暗号解析を行うことはほとんどありません。
Microsoft は、次の環境での RNG 実装の検証を取得しています。
これらのテストは、「製品のセキュリティを測る尺度を提供するのではなく、承認された様々なRNG仕様への適合性をテストするために設計されています。[...] したがって、検証は製品全体のセキュリティの評価または承認として解釈されるべきではありません。」結果として、アルゴリズムのセキュリティについて結論を導き出すことはほとんどできません。FIPS評価は必ずしもソースコードを検査したり、RNGシードの生成方法を評価したりするわけではありません。[9]
RNG検証リストには、以下の通知が記載されています。「2016年1月1日現在、SP800-131A改訂1版『移行:暗号アルゴリズムおよび鍵長の使用の移行に関する勧告』に基づき、FIPS 186-2、[X9.31]、および1998年版[X9.62]で規定されているRNGの使用は承認されていません。このリストは、歴史的目的のみに提供されています。」[10]
Windows 開発者には、CryptGenRandom 機能にアクセスするための代替手段がいくつかあります。これらの代替手段は同じアルゴリズムを呼び出し、同じセキュリティ特性を共有しますが、他の利点がある場合があります。
プログラムにWindows XPまでの下位互換性が必要な場合は、Windows API関数( [3]RtlGenRandomに記載)を呼び出して、以下に示すように安全なランダムデータを生成することができます。これが問題にならない場合は、代わりに新しい呼び出しを使用してください。
advapi32.dllBCryptGenRandom
これまで私たちは開発者に対し、鍵、ノンス、パスワードを生成するためにrandなどの関数ではなく、暗号的に安全な乱数を生成するCryptGenRandomなどの関数を使用するよう常に指示してきました。CryptGenRandomの問題は、CryptoAPI(CryptAcquireContextなど)を読み込む必要があることですが、他の暗号関数を使用している場合は問題ありません。
Windows XP以降のデフォルトのインストールでは、CryptGenRandomはADVAPI32!RtlGenRandomという関数を呼び出します。この関数では、CryptAPIの要素をすべてロードする必要はありません。実際、Whidbeyの新しいCRT関数であるrand_sはRtlGenRandomを呼び出します。[11]
.NETを使用するプログラマーはRNGCryptoServiceProviderクラスを使用する必要があります。[12]
CNG [13]は、廃止されたCrypto APIの長期的な代替手段です。CNGは、同等の関数であるBCryptGenRandom [14]に加え、鍵生成専用の関数も提供しています。
rand_s使用します。 [11]RtlGenRandomSunMSCAPI Windows版JREのOpenJDKおよびOracleディストリビューションで利用可能なJCAプロバイダは、Windows - PRNGというアルゴリズム名を持つSecureRandom実装を提供しています。このクラスは、ランダムバイトまたはシードバイトのクエリをすべてCryptGenRandomに転送し、追加のシードバイトを設定します。[16]注: Windows Vista SP1およびWindows Server 2008以降、乱数ジェネレーターはNIST SP 800-90標準で規定されているAESカウンターモードに基づいています。[...] Windows 10: Windows 10以降、デュアル楕円曲線乱数ジェネレーターアルゴリズムは削除されました。このアルゴリズムの既存の使用は引き続き機能しますが、乱数ジェネレーターはNIST SP 800-90標準で規定されているAESカウンターモードに基づいています。
{{cite web}}: CS1 maint: アーカイブされたコピーをタイトルとして (リンク)