安全な乱数を詳しく解説した記事

この記事は、Huawei クラウド コミュニティ「[セキュリティの攻撃と防御] 実践的なトピックを簡単に解説 - 安全な乱数」 (著者: MDKing) から共有されたものです。

乱数の使用シナリオ

乱数を使用して、安全なシナリオと安全でないシナリオを分類します。安全以外のシナリオはできるだけ早く生成する必要があります。セキュリティ シナリオで使用される乱数は、予測できないように十分に安全である必要があります。

セキュリティ以外の一般的なシナリオ:

  • データのインデックス番号と識別。

  • ファイルの名前またはディレクトリ。

  • UUID、ユーザーID、ランダムなパディングバイト。

一般的なセキュリティ シナリオには次のシナリオが含まれますが、これらに限定されません。

  • IV、ソルト値、キーなどの生成など、暗号化アルゴリズムの目的で使用されます。

  • セッション ID (sessionId) の生成;

  • アルゴリズムでの乱数生成に挑戦します。

  • 検証コードの乱数生成;

暗号化された安全な乱数

セキュリティ シナリオで使用される乱数は、暗号的に安全な乱数である必要があります。

暗号化の意味での安全な乱数は、次の 2 つのカテゴリに分類されます。

  • 真の乱数発生器によって生成された乱数。

  • 暗号的に安全な擬似乱数生成器によって生成された大量の乱数に、真の乱数生成器によって生成された少量の乱数がシードされます。

製品で使用できる、暗号的に安全な非物理的な真の乱数生成器として知られているものは次のとおりです。

  • Linux オペレーティング システムの /dev/random デバイス インターフェイス (ブロッキングの問題があります)

  • Windows オペレーティング システムの CryptGenRandom() インターフェイス

真の乱数生成器は乱数を生成するためにリソース (エントロピー) を必要とし、リソースが不十分な場合はブロックされるため、暗号的な意味での安全な乱数は必ずしも真の乱数生成器によって生成される必要はないことがわかります。したがって、ビジネスで乱数を使用する頻度が低い場合は、すべて真の乱数を使用することを検討できます。ビジネスで乱数を頻繁かつ大量に使用する場合は、セキュリティと効率のバランスをとる方法を使用する必要があります。乱数を生成するメインのジェネレータとして擬似乱数ジェネレータを使用し、そのシードを設定するために真の乱数サイクルを使用します。 。

SecureRandom オブジェクトで乱数を生成するには、次の乱数を生成するメソッド (nextInt、nextBytes など) と、シードを生成するメソッド (generateSeed など) の 2 つのメソッドがあります。

new SecureRandom() を使用して作成されるオブジェクトの nextXXX およびgenerateSeed メソッドの乱数のソースは、Linux システムでは /dev/urandom であり、生成される乱数はすべて安全でない乱数です​​。

SecureRandom.getInstance("SHA1PRNG", "SUN") を使用して作成されたオブジェクト nextXXX は安全でない乱数を生成し、generateSeed は安全な乱数 (Linux ではソースは /dev/random) を生成するため、SHA1PRNG アルゴリズムを使用して設定します。良いサイクルで再植林するというロジックは、理論的には実現可能です。ただし、同社の暗号アルゴリズム関連要件によると、安全な乱数を生成するための SHA1PRNG アルゴリズムの使用は 2023 年から禁止されます。

安全な乱数の一般的に推奨される使用法

原則として、エントロピー ソースの再シードや更新などのロジックを自分で実装することは推奨されず、JDK によってカプセル化されたメソッドを直接使用することをお勧めします。

暗号的に安全な乱数を使用するには、主に 3 つの方法があります。

1. SecureRandom.getInstance(" NativePRNGBlocking ")

パラメーターは NativePRNGBlocking で構成する必要があります。利点は、nextXXX メソッドとgenerateSeed メソッドがすべて生成された真の乱数であるため、非常に安全であることです。欠点は、毎回真の乱数であるため、パフォーマンスが低く、問題が発生する可能性があることです。問題をブロックしている可能性があります。いくつかの一般的なパラメータの比較は次のとおりです。

パラメータ値 説明する nextXXX の乱数ソース generateSeed の乱数ソース 乱数の品質 ブロックされているかどうか(実際の検証なし、読者の判断)
SHA1PRNG
乱数ジェネレーターの初期シードは、システム プロパティと java.security のエントロピー収集機能を介して行われます。初期シード処理が完了すると、エントロピー収集デバイスに依存しなくなります。 それ それ 危険な ブロックしていない
ネイティブPRNG
最初のシード処理が完了した後も、システムのエントロピー収集デバイスから乱数を取得する必要があります。これがネイティブの意味です。nextBytes() は /dev/urandom デバイスから乱数を取得し、generateSeed() は /dev/random から乱数を取得します。 /dev/urandom /dev/ランダム より安全な 乱数の取得はブロックされませんが、シードの取得はブロックされる可能性があります。
ネイティブPRNGブロッキング
nextBytes() とgenerateSeed() は両方とも /dev/random から乱数を取得します /dev/ランダム /dev/ランダム 最も安全な ブロックされる可能性が高い
ネイティブPRNGノンブロッキング
nextBytes() とgenerateSeed() は両方とも /dev/urandom から乱数を取得します /dev/urandom /dev/urandom 危険な ブロックしていない

2. SecureRandom.getInstanceStrong()

JDK 8 で導入されたこの機能は、主に、特定のパラメーターを適用するときに getInstance が取得される乱数の品質が十分に安全であることを保証できないという問題を解決し、プログラミングを簡素化します。各プラットフォームで利用可能な最も強力な SecureRandom 実装のインスタンスを返します。これは、システムで利用可能な最強のアルゴリズムを呼び出します。これは、$JAVA_HOME/jre/lib/security/java.security の securerandom.strongAlgorithms によって指定されます。

securerandom.strongAlgorithms のデフォルト設定は通常 NativePRNGBlocking:SUN です。この設定では、getInstanceStrong() は getInstance("NativePRNGBlocking") と同等です。

3. SecureRandom.getInstance("DRBG",...)

JDK 9 以降、HASH-DRBG、HMAC-DRBG、CTR-DRBG などの NIST SP 800 90-A 標準に準拠し、さまざまな OS に適した新しい DRBG 擬似乱数ジェネレーターが Sun によって提供されています。同社のパスワード アルゴリズム関連の要件に準拠しているため、JDK 9
以降を使用する場合は、この方法を使用して安全な乱数を生成することをお勧めします。この乱数生成方法は、安全性と効率性の両方を考慮した真の乱数の定期的な再シードをカプセル化したものであるため、安全な乱数が高頻度で生成されるシナリオで使用できます。

推奨される書き込み方法については、プログラミング仕様を参照してください。

1.png

要約する:

安全な乱数を低頻度で使用する (パフォーマンス要件なし) ビジネス シナリオでは、SecureRandom.getInstance("NativePRNGBlocking") または SecureRandom.getInstanceStrong() を使用できます。

(パフォーマンス要件のある) 安全な乱数を頻繁に使用するビジネス シナリオでは、SecureRandom.getInstance("DRBG",...) メソッドのみを使用できます。

上記の方法のいずれもビジネス シナリオのニーズを満たせない場合は、再シードやエントロピー補充などのロジックを自分で実装することを検討してください (推奨されず、通常は使用できません)。

実際の検証

SHA1PRNG型乱数生成器を使用して、同じシードを設定した上で同じ乱数列が生成できるか検証します。

2.png

実行結果は次のとおりです。何度繰り返しても、最初のシードが同じであれば、その後のシーケンスは同じで固定されている必要があることがわかります。

3.png 4.png

したがって、安全でない乱数生成器によって実装されたコード ロジックが使用される場合、攻撃者が一定数の乱数シーケンスを習得すると、最初のシードを推定し、その後生成される乱数シーケンスの特定の内容を完全に予測することが可能になります。 。

真の乱数を使用してシードを設定する場合 (現在の書き込み方法は一例であり、推奨される書き込み方法ではありません)

5.png

各実行はランダムであり、セット シードは真の乱数発生器によって生成されるため、予測不可能であることがわかります。

6.png 7.png

学生の中には、真の乱数発生器の速度は本当にそんなに遅いのか、と興味を持つ人もいるでしょう。実際の検証において、真性乱数生成器と擬似乱数生成器を使用した場合の性能比較は以下の通りです。

8.png

クリックしてフォローし、できるだけ早くHuawei Cloudの新しいテクノロジーについて学びましょう~

IntelliJ IDEA 2023.3 と JetBrains Family Bucket の年次メジャー バージョン アップデート 新しいコンセプト「防御型プログラミング」: 安定した仕事に就く GitHub.com では 1,200 を超える MySQL ホストが稼働していますが、8.0 にシームレスにアップグレードするにはどうすればよいですか? Stephen Chow の Web3 チームは来月、独立したアプリをリリースする予定ですが、 Firefox は廃止されるのでしょうか? Visual Studio Code 1.85 がリリース、フローティング ウィンドウ 米国 CISA、メモリ セキュリティの脆弱性を排除するために C/C++ の放棄を推奨 余成東 : ファーウェイは来年破壊的製品を発売し、業界の歴史を書き換える TIOBE 12 月: C# は今年のプログラミング言語になると期待される 論文30年前にLei Junが書いた「コンピュータウイルス判定エキスパートシステムの原理と設計」
{{名前}}
{{名前}}

Supongo que te gusta

Origin my.oschina.net/u/4526289/blog/10319920
Recomendado
Clasificación