2013-11-22 17 views
9

DSA署名アルゴリズムを使用してファイル/ファイルにアクセスしたかどうかを調べる小さなプログラムを作成しようとしています。DSA暗号化サービスプロバイダの同じキーで同じデータを署名すると、結果が異なる

私はこの問題を説明するための小さなサンプルコードを提供します。 ファイルc:\ Temporary \ Temp.txtがあるとします。 私たちのプログラムには2つのボタンがあります。最初のボタンをクリックすると、ファイル名と最後のアクセス時刻にデジタル署名 が作成されます。また、パラメータをエクスポートして保存します。 2番目のボタンをクリックすると、以前にエクスポートしたパラメータを使用して同じファイル上の署名を再作成し、新しい署名と前の署名を比較します。

ここでの問題は、プログラム(常に)が私にファイルにアクセスしたという結果を与えることです!

問題を見つけるためにデバッガを使用し、2つのbutton_clickイベントの間ですべての変数値が同じであることと、その違いが署名プロセスで発生することを確認しました。

問題がどこにあるか教えてください。あなたは==演算子を使用して2つのバイト配列を比較している

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Data.SqlClient; 
using System.Security.Cryptography; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     string filename = @"C:\Temporary\Temp.txt"; 
     DSAParameters parameters; 
     byte[] data_to_sign, signature; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 

    private void Sign_button_Click(object sender, EventArgs e) 
    { 
     FileInfo f_info = new FileInfo(filename); 
     string file_information = f_info.FullName + f_info.LastAccessTime; 
     UnicodeEncoding byteEncoder = new UnicodeEncoding(); 
     data_to_sign = byteEncoder.GetBytes(file_information); 
     DSACryptoServiceProvider dsaprovider = new DSACryptoServiceProvider(); 
     parameters = dsaprovider.ExportParameters(true); 
     signature = dsaprovider.SignData(data_to_sign); 
     label1.Text = " Signature generated"; 
    } 

    private void Verify_button_Click(object sender, EventArgs e) 
    { 
     FileInfo f_info = new FileInfo(filename); 
     string file_information = f_info.FullName + f_info.LastAccessTime; 
     UnicodeEncoding byteEncoder = new UnicodeEncoding(); 
     data_to_sign = byteEncoder.GetBytes(file_information); 
     DSACryptoServiceProvider dsaprovider2 = new DSACryptoServiceProvider(); 
     dsaprovider2.ImportParameters(parameters); 
     byte [] signature2 = dsaprovider2.SignData(data_to_sign); 
     if (signature == signature2) 
      label1.Text = "The file hasn't been accessed"; 
     else 
      label1.Text = "Opp... The file has been accessed"; 

    } 
} 
} 

答えて

10

: は、ここでは、コードです。参照によってそれらを比較しています。内容が同じであっても、2つの異なるバイト配列インスタンスでは常にfalseです。代わりにその内容を比較する必要があります。

実際に内容を比較するには、this questionのさまざまなコードを使用してください。あなたはSystem.Linqを持っている場合は、あなたの使用して宣言で

if (signature.SequenceEqual(signature2)) 

代わり

if (signature == signature2) 

のあなたのような何かを行うことができます。

+0

はいSequenceEqualを比較したり、比較する文字列に変換し、言いました。 –

4

あなたはDSAを完全に欠場します。 DSAは署名アルゴリズムであり、デジタル署名検証アルゴリズムを使用して検証する必要があります。実際、DSAは乱数を生成するために使用されるたびに異なる署名を生成するように設計されています。 ここで必要なのは、SHA-256やKeccakのようなハッシュアルゴリズムです。

+0

DSAはSHA1ハッシュアルゴリズムを使用していますが、 '.SignData()'メソッドを呼び出すとSHA1ハッシュが返されますが、OPがハッシングにDSAを使用している場合にのみ最適な選択ではない可能性があります – geedubb

+0

@geedubb DSAではSHA1ハッシュを生成しますが、DSAシグネチャを生成します。 DSAは入力をハッシュしますが、OPの要件とは関係ありません。 – Aris

2

あなたは、ファイル名や最終アクセス時刻が変更されていないという事実に依存していることdeciion、の基礎として

string file_information = f_info.FullName + f_info.LastAccessTime; 

を使用しています。

  • あなたは がタイプのFileInfoのオブジェクトを作成するときに、.NETフレームワークは、内部的に何をするか分かりません。すでに ファイルにアクセスしている可能性があります。または、FullNameプロパティを使用するときにファイルにアクセスします。
  • 同じファイルのプロパティに再度アクセスするときには、Refresh()も呼び出す必要があります。それ以外の場合はcached informationを使用することがあります。
  • LastAccessTimeの信頼性は高くありません。パフォーマンス上の理由から、 Windows 7ははそのフラグを更新しません。詳細は、「Windows 内部6」を参照してください。
  • なぜこの場合、DSAを使用していますか ? file_information文字列 を直接比較することができます。署名をしてもしなくても差は出ません。
  • 同様セバスチャンはバイト[]平等ため正しく
関連する問題