scrypt
や bcrypt
のようなものを使用してパスワード保護を「強化」することのセマンティクスとセキュリティへの影響について疑問に思っています。 PGP秘密鍵。基本的に、私はパスワードのscrypt
をPGP秘密鍵のパスワードとして使用することの意味について質問しています。
私の理解では、PGP鍵ペアは基本的に 2つの大きな素数とその積 であり、秘密鍵は 対称的に暗号化されている です。
私の現在の考えは、2つの主な理由から、これは非常に良い考えだということです。まず、これにより、パスワードが辞書攻撃を受けにくくなります。これは、scrypt
の出力が辞書ワードである可能性が非常に低いためです(確認できます)。
2番目の、より複雑な理由は、ブルートフォース攻撃に必要な計算能力です。
秘密鍵に格納されている(復号化された)素数の単一の推測をチェックするコストがA
であると仮定しましょう。暗号化された秘密鍵が危険にさらされているとすると、1つの推測をチェックするコストはB
であると想定します。 scrypt
の計算コストがC
であると仮定します。
2048ビットの素数をブルートフォースする場合、最大でpi(2^2048) * A
のコストがかかります。ここで、pi(x)
はx
未満の素数の数です。秘密鍵が危険にさらされていると仮定し、20文字(160ビット)のパスワードの不当な上限を仮定すると、パスワードをブルートフォースする最大コストは2^160 * B
です。 N
-文字(N*8
ビット)scrypt
の結果であることがわかっているパスワードを持つ侵害されたキーを想定すると、パスワードをブルートフォースする最大コストは2^160 * C * B
OR 2^(N*8) * B
(攻撃者がscrypt
を使用しようとするか、ハッシュ自体を解読する可能性があるため)。
標準の推定量pi(2^2048) ~= 2.28*10^613
を使用することに注意してください。
計算のためにA = 1
を修正しましょう。そして、整数乗算のコストが低いことを考えると、これは妥当と思われる仮定B >= 2
です。
scrypt
の場合、C
は可変です。 C = 10
(2つの大きな数を乗算するよりもscrypt
を計算するのが10倍難しい)を考慮すると、次のようになります。
2.28*10^613
2^160 * 10 * 2 = 2.9 * 10^49
OR 2^(N*8) * 2 = 2^(8N +1)
ここで、2^(8N +1) = 2.9 * 10^49
はN = 21
付近にあります。つまり、C = 10
の場合、ハッシュよりもハッシュへの入力を簡単に解読できるように、21文字のハッシュのみが必要です。もちろん、秘密鍵自体を持っていることは依然として有益です。
ただし、scrypt
の難易度はさまざまであり、10
はおそらく非常に控えめな見積もりです。代わりにN = 128
を修正した場合:
2.28 * 10^6131
2^160 * C * 2
または2^1024 * 2
ここで、2^160 * C * 2 = 2^1024 * 2
はC = 1.23 * 10^200
あたりにありますが、これは明らかに完全に無理です。これは、妥当なハッシュ長の場合、ハッシュ自体よりもハッシュへの入力をクラックする方が常に良いことを意味します。
明らかに、N = 256
の値を使用する場合、C > 1
である限り、ハッシュを解読するよりも実際にキーを解読する方が簡単です。
C >= 1000
を想定するのは合理的だと思います。この仮定で、N=256
を修正し、パスワードがP
文字であると仮定します。
2.28 * 10^6131
2^(8P) * 1000 * 2
または2^2048 * 2
キーを解読するよりもパスワードを解読するのを難しくするには、P = 255
前後が必要になりますが、これは不合理に思えます。
したがって、scrypt
やbcrypt
のようなタフなハッシュ関数を使用すると、タフネスを控えめに見積もっても、キーの推測の難しさを大幅に改善できるようです。また、パスワードをハッシュすることは、キーが危険にさらされた状況で役立つ可能性があるようですが、それほど多くはありません。
他に考慮すべき懸念事項はありますか?私は現在、キーパスワードがpassphrase + hash(another passphrase)
である一種の「デュアルパスワード」アプローチを検討しています。これは、私が見落としていたかもしれないハッシュの結果でプライムを暗号化するという奇妙な数学的特性を軽減するようです。
編集:ただ先制的に、私は(完全に)ばかではありません。 PGPが独自のハッシュメカニズムS2K
を定義していることは承知していますが、「適切な」バージョンのハッシュを使用する人はほとんどいません(デフォルトでは有効になっていません)。適切な構成機能がないため、簡単に解読できます。 GPUのようなアクセラレータで。ですから、はい、ここではある程度「ダブルハッシュ」を提案していますが、scrypt
はプリセットデータを使用した特定のハッシュアンドグラブアプローチを使用し、S2K
は古き良きファッション指数を使用しています-そして-ビット単位のアプローチ。私の暗号学クラスを覚えていれば、一方の出力がもう一方のドメイン内にある限り(この場合はそうです)、関数の組み合わせに問題はありません。
カスケードパスワードハッシュ関数の通常の問題は、CPUをめぐって競合することです。設定可能な反復回数を持つ各パスワードハッシュ関数は、可能な限り高く設定する必要があります。制限は、使用可能な処理能力とユーザーとしての忍耐力の組み合わせです。 bcrypt(またはscrypt)をPGPの機能(S2K変換)と組み合わせると、CPUと忍耐力のリソースを共有する必要があるため、どちらか一方だけで実行できるほど高く両方の設定をクランクすることはできません。両方の機能の間。ただし、非常に不均衡な設定を使用する場合(たとえば、S2Kの反復回数が非常に少ない、または反復されていないS2Kで、bcrypt/scrypt層の保護全体を報告する)、bcryptまたはscryptの出力を使用しても問題はありません。過度のスペース削減が発生しない限り、PGPの「パスワード」として(ここでは問題ありません:PGPは非常に長いパスワードを切り捨てずに受け入れます)。
ただし、実際的な問題が発生する可能性があります。特に、bcryptとscryptはsaltedであり、これは、それらの出力がパスワードとsaltの両方の決定論的関数であることを意味します。ソルト値をどこかに保持する必要があります。そうしないと、パスワードを覚えていても暗号化キーを再計算できません。 OpenPGP形式 には、追加のソルト用の使いやすい配置は含まれていません。
オープンソースのOpenPGPライブラリ( GnuPG など)を、新しい種類の「S2K」として(通常のS2Kに加えてではなく、置換)。このフォーマットには 256種類のS2K の余地があり、11スロットはその種のプライベート実験用に正確に予約されています。
RSA素数などでの長い計算は、次の2つの主な理由により大幅にオフになっています。
特に可能なプライム除数を試すことによって、RSAキーを「ブルートフォース」することはありません。 RSA鍵には多くの数学的構造があり、その構造を解明することによって、つまり 素因数分解 で壊れます。これは、すべての素数を列挙するよりもはるかに効率的です(これは、「試行割り算」として知られる非常に大雑把な因数分解アルゴリズムであり、 はるかに優れています )。これが、200ビット程度の小さいキーに固執するのではなく、1000ビットを超えるRSAキーを使用する理由です。
「既存の予測可能なテクノロジーでは解決できない」以上のセキュリティレベルはありません。現在のしきい値(人類全体が世界規模の大規模なクラッキング作業に協力していると仮定)は、おそらく約2です。100 操作、つまり10に近い30。ここでのボトルネックはエネルギーです。このようなレベルを超えるコストは、意味のない数値です。コスト値10で支払うことは意味がないか、少なくとも実用的意味がありません。631 または22048。
人々が通常行うことは、「合理的な」セキュリティレベル、つまり、今後40年間、ある程度の余裕を持って人類が解読できないものを目指すことですが、それを超えることはありません。これは、2048ビットのRSAキーと80ビットのパスワードエントロピー(適切なスローダウン係数、つまりbcryptまたはscryptの内容)を示しています。
キーサイズを選択するためのガイダンスとして、さまざまな機関によって作成された、タイプとサイズに応じたキー強度の相互推定を調べるには、 このサイト を参照してください。大きすぎるキーまたはパスワードは深刻なオーバーヘッドを引き起こす可能性があります(RSAキーのサイズを2倍にすると、秘密キーの操作は8倍遅くなります。パスワードのサイズを2倍にすると、覚えておく必要があります2倍の文字)。