3

私は小さなJavaセルフチェックプログラムを分析する必要があります ここにサンプルがあります

public class tamper {
      public static int checksum_self () throws Exception {
          File file = new File ("tamper.class");
          FileInputStream fr = new FileInputStream (file);
          int result;                   // Compute the checksum

          DigestInputStream sha = new DigestInputStream(fr, MessageDigest.getInstance("SHA"));
   byte[] digest = sha.getMessageDigest();

    int result = 12  // why???
    for(int i=0;i<=digest;i++)
     {
     result = (result + digest[i]) % 16 /// modulus 16 to have the 16 first bytes but why ??
    }

    return result;
      }

      public static boolean check1_for_tampering () throws Exception {
            return checksum_self () != 10; 
      }

      public static void main (String args[]) throws Exception {
          if (check1_for_tampering ()) {
            System.exit (-1);
          }

      }
}

しかし、mod 16 を実行して結果 = 12 を入れる理由がよくわかりません。

4

3 に答える 3

2

おそらく、モジュロがないとチェックサムを埋め込むのが非常に難しいからです。プログラムを作成したと想像してください。一度にすべてを書き込むことができますが、正しいチェックサムを得るには、実験する必要があります。

チェックサム モジュロ 4 を書いたとします。最初に値を 0 と比較します。プログラムを実行しますが、改ざんされていることが検出されます。なんで?ソースコード全体を書くまでチェックサムがわからないからです。また、チェックサム値が埋め込まれているため、ソース コードが変更されるたびにチェックサムが変更されます。

つまり、自分のしっぽを追いかける犬のようなものです。または自分の尻尾を食べるヘビ。技術的に言えば、これはフィードバック ループを含む動的システムの状況です。わかりました、それは十分なアナロジーです。

それを機能させる唯一の方法は、実験することです。チェックサムをゼロにしてコンパイルを開始します。正しく推測する確率は約 1/4 であるため (4 を法とする任意の値は 4 つの値を持つことができるため)、おそらくそれが (誤って) 改ざんされたことを認識します。次に、値を 1 に変更します。うまくいかない場合は、2 に変更し、最後に 3 に変更します。

それらの 1 つが一致する可能性がありますが、モジュロ値が低いと、改ざんを検出する可能性が低くなります。したがって、値 16 は基本的に妥協です。モジュロ値をできるだけ低くして、推測の量を適度に少なくしたいと考えています。一方、モジュロ値を高くすることで、アルゴリズムを完全に改ざん防止する必要があります。

于 2011-01-03T20:11:49.847 に答える
1

おそらく、このサンプル コードの作成者は、ダイジェストの 16 バイト全体をチェックしたくなかったので、ハッシュからハッシュを作成することにしました。これが mod 16 操作の目的です。ダイジェストの最初の 16 バイト (より具体的には、ダイジェストの 4 ビット ダイジェスト) をモジュロ 16 でハッシュし、結果を 10 と比較します。間違っている場合は訂正してください。ただし、値は 12 と10 個がランダムに選択され、実際のハッシュとチェック対象の値が一致するようにします。

ピーターが言ったように、これは完全な解決策ではありません。

于 2011-01-03T20:11:27.920 に答える
1

mod 16 は、最後の 16 バイト、または最下位 4 ビットを提供しません。n / 16 の余りが得られます。これは、正と同じくらい簡単に負になる可能性があり、ダイジェストのバイト数を累積する良い方法ではありません。

2 つのランダム ファイルが同じ結果を生成する可能性は 1/31 です。

私が考えることができる簡単な方法は、はるかに識別力があるでしょう

return new String(digest, 0).hashCode();

2 つのファイルが同じハッシュ コードを持つ確率は 40 億分の 1 で、コードははるかに短くなります。

于 2011-01-03T20:07:46.007 に答える