web-dev-qa-db-ja.com

Signalで安全番号を計算するときに、なぜ5200回繰り返すのですか?

Signal の安全番号は、会話のユーザーの公開鍵とその電話番号のハッシュから取得されます。安全番号は、会話がMITM-edでないことを確認するために使用されます。

安全番号を導き出すとき、 SHA-512は5200回繰り返されますSignal Safetyブログ によると、ハッシュに埋め込まれた電話番号に関するプライバシーの問題がありました。ただし、可能な電話番号のセットが比較的小さいことを考えると、これが理由になることはありません。

ソースコード内のコメント:

反復回数が多いほど、セキュリティレベルが高くなります。

  • 1024〜109.7ビット
  • 1400> 110ビット
  • 5200> 112ビット

それでは、Safety Numbersの計算を意図的に遅くする理由は何ですか?

おまけ:おおよそのセキュリティレベル(1024 SHA-512ハッシュ〜109.7ビット)はどのように計算されますか?

18
bgd223

コメントはあまりよく説明されていませんが、私はその背後にある数学を決定したと思います。安全番号は60桁の10桁ですが、30桁の2つの半分で作成されます。1つは電話番号と公開鍵に基づいており、もう1つは話している相手の電話番号と公開鍵に基づいています。

高いエントロピー値がエントロピーの不必要な損失なしに30桁の数値に変換されると仮定すると、ログには2(1030)≈99.66ビットのエントロピー、99.66 "セキュリティのビット"と同等(攻撃者が2の後で安全番号と一致する可能性が50%あることを意味します)99.66/ 2 = 298.66 ハッシュ)。何度も繰り返すと、セキュリティのビットが増加します(攻撃者が試行するたびにハッシュ操作の数が増えるため)。

ログ2(1030 ×1024)≈109.66

ログ2(1030 ×1400)≈110.11

ログ2(1030 ×5200)≈112.00

これは、特定のセキュリティ番号に一致するために攻撃者が実行する必要があるハッシュの数ですが、攻撃者が送信するメッセージをreadにできるようにしたい場合は、プライベートを知る必要がありますハッシュで使用した公開鍵と一致する鍵。 RSAキーペアの生成は計算コストがかかりますが、ECCははるかに高速です。キーペアの生成が十分に高速である場合は、ハッシュを反復して安全番号に対する攻撃の下限を増やすことは理にかなっています。

16
AndrolGenhald

安全番号は、安定した識別子とユーザーの公開鍵の派生です。安全数値は、会話の両方の人に対して計算されます。

本当に重要なコードはこのスニペットです

byte[] publicKey = getLogicalKeyBytes(unsortedIdentityKeys);  
byte[] hash = ByteUtil.combine(ByteUtil.shortToByteArray(FINGERPRINT_VERSION), publicKey, stableIdentifier.getBytes());  

for (int i=0;i<iterations;i++) {
        digest.update(hash);
        hash = digest.digest(publicKey);
      }

何が起こっているかというと、指紋バージョン、公開鍵、安定した識別子を入力として使用し、SHA-512で1回ハッシュしています。 2回目の反復では、作成したハッシュに公開キーを付加し、2回目にハッシュします。

公開鍵を追加してハッシュを繰り返すこのプロセスは、指定された反復回数だけ続けられます。

なぜ過去よりも多くの反復を行う必要があるのですか?

これは、ハッシュの場合の根本的な問題によるものです。これはハッシュの衝突の可能性です。

私が攻撃者だとしましょう(イブ)。アリスはボブと話したいので、シグナルは彼女の公開鍵をボブに送信しますが、イブは公開鍵を傍受して自分の鍵に置き換えます。通常、キーが変更されたことが示され、安全番号が変更されます。

イブが十分なリソースを持っている場合、彼女は安全番号と一致する公開鍵を作成できます。この脅威に対抗するために、イブが5200ラウンドのハッシュ後に発生する衝突を見つけ、そのラウンドごとに同じキーを追加する必要があるようにします。

ハッシュの各ラウンドで衝突の検出が線形的に計算コストが高くなるため、これは計算的に実行不可能になります。現在選択されている反復回数は、通常、このスタイルの攻撃にかかる時間に基づいて、認識された脅威のリソースに基づいて計算されます。

具体的になぜ5200を選んだのかについて、Signalから計算を見つけることができません。

6
Daisetsu

ソースコードのこれらのコメントは間違っています。開発者は彼が書いたものを本当に理解していませんでした。

ここに彼のコメントがあります:

反復回数が多いほど、セキュリティレベルが高くなります

このステートメントは部分的に正しいです。つまり、ブルートフォーシングにはより多くのリソースが必要であり、この観点からより安全です。ただし、ハッシュの衝突の確率はハッシュスペースのサイズにのみ依存します。つまり、ハッシュの長さに依存します(ハッシュが均等に分散していると想定)。反復回数には依存しません。つまり、ハッシュの衝突の観点からは、notより安全です。

簡単な例。ハッシュが1バイト、つまり8ビットで構成されているとします。安全ではないため、実際には誰もそれを使用しません。しかし、何が起こっているのかを簡単に理解できます。 8ビットは、256の異なるハッシュがあることを意味します。 5200または1000000の反復回数に関係なく、最終的に256ハッシュの1つを取得します。 256の値の1つを取得する確率はどれくらいですか? 1/256です。

では、なぜsmbなのか。 5200反復について話している-> 112ビット?

繰り返しますが、最初に8ビットのハッシュ= 256の異なる値を取ります。特定のハッシュを生成するメッセージを取得するために必要なメッセージの数は?最悪の場合、256の計算が必要になります。ここで、元のハッシュ関数の2回の反復を使用するハッシュ関数を使用するとします。最悪の場合、総当たりで256回の反復が必要になるため、各反復は元の2倍長くなります。 512の元のハッシュ、つまり2 ^ 9のような時間が必要であることを意味します。これは、元のハッシュ関数で2 ^ 9の値をブルートフォースすることに相当します。 8反復を使用する場合、必要な時間は256 x 8 = 2 ^ 11です。これは、2 ^ 11値に元のハッシュ関数を使用するようなものです。つまり、ハッシュ長を8ビットから11ビットに増やすようなものです。 5200反復の場合、これはlog2(5200)〜= 12ビットのハッシュを増やすようなものです。

OPでは、エントロピーは99.7ビットです。 5200回の反復によるハッシュのブルートフォーシングは、1回の反復によるハッシュのブルートフォーシングとほぼ同じ時間を要しますが、約12ビット長くなります。 log2(5200)〜= 12.3; 99.7 + 12.3 = 112。

もう一度:同等の反復回数を増やすことは、ハッシュサイズを増やすことと同じだとか、エントロピーを増やすとかは正しくありません。必要なCPU時間を増やすだけです。しかしエントロピーは同じままです、ハッシュ衝突の確率は同じままです。

1
mentallurg