CryptGenRandomは、 Microsoft CryptoAPIに含まれる、暗号的に安全な疑似乱数生成関数です。Win32プログラムでは、乱数生成が必要なあらゆる場所でMicrosoftはこの関数の使用を推奨していました(その後、 BCryptGenRandomに置き換えられました。下記参照)。Kernel32での同等の関数はRtlGenRandomです
ヘブライ大学が2007年に発表した論文では、Windows 2000におけるCryptGenRandomの実装にセキュリティ上の問題があることが示唆されています(攻撃者がマシンを制御下に置いていると仮定した場合)。マイクロソフトは後に、同じ問題がWindows XPにも存在するものの、Vistaには存在しないことを認めました。マイクロソフトは2008年半ばにWindows XP Service Pack 3でこのバグの修正プログラムをリリースしました。[ 1 ]
CryptGenRandomは、非推奨のWindows CryptoAPIに属しているため、非推奨となりました。最新のCryptography API: Next Generation (CNG) の代替は、BCryptGenRandom(および基盤となるProcessPrngとSystemPrng)です。[ 2 ]
Win32 APIには、 Windowsアプリケーションで使用するためにMicrosoftが提供する暗号化プリミティブのセットであるMicrosoft CryptoAPIによる包括的な暗号化サポートが含まれています。TLSサポート( Schannel API経由)やコード署名などのWindowsテクノロジはこれらのプリミティブに依存しており、これらのプリミティブは暗号的に安全な擬似乱数生成器(CSPRNG)に依存しています。CSPRNGは、Microsoft CryptoAPIに付属する標準のCSPRNGです CryptGenRandom
Microsoftが提供する暗号化プロバイダーは、現在と呼ばれる内部関数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アルゴリズムの詳細は当時公開されていなかったため、Dorrendorf氏のチームはリバースエンジニアリングツールを用いてその動作を解明しました。彼らの論文は、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 ]RtlGenRandomSunMSCAPIWindows版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: アーカイブされたコピーをタイトルとして (リンク)