2013-11-22 19 views
9

DSA İmzalama algoritması kullanılarak dosya/dosyalara erişilip değiştirilmediğini öğrenebilecek küçük bir program oluşturmaya çalışıyorum.Aynı verilerle aynı veriyi imzalarken DSA kripto sağlayıcısında

Sorunu açıklamak için size bu küçük örnek kodu vereceğim. Farz edelim ki bir dosyamız var c: \ Temporary \ Temp.txt. Programımızda 2 düğmemiz var. İlk tuşa bastığımızda, dosyanın adı ve üzerinde son erişim zamanı olan bir dijital imza oluşturuyoruz. Ayrıca parametreleri de dışa aktarıyoruz ve saklıyoruz. İkinci tuşa tıkladığınızda, daha önce dışa aktardığımız parametreleri kullanarak aynı dosyadaki imzayı yeniden oluştururuz ve yeni imzayı bir önceki ile karşılaştırırız.

Buradaki problem, programın (her zaman), dosyaya erişildiğini gösteren bir sonucu vermesidir !!

Sorunu bulmak için hata ayıklayıcıyı kullandım ve tüm değişken değerlerin 2 button_click olayı arasında aynı olduğunu ve farkın imzalama işleminde gerçekleştiğini gördüm.

Lütfen sorunun nerede olduğunu söyler misiniz? Sen == operatörünü kullanarak iki bayt dizileri karşılaştırdığınız

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"; 

    } 
} 
} 

cevap

10

: İşte kodudur. Bunları referans olarak karşılaştırıyorsunuz ve bu, içerikleri aynı olsa bile, iki farklı bayt dizisi örneği için her zaman yanlıştır. Bunun yerine içeriğini karşılaştırmanız gerekiyor.

İçeriği gerçekten karşılaştırmak için çeşitli kod parçalarını this question'dan kullanın. Eğer System.Linq varsa lütfen kullanarak beyanlarında

if (signature.SequenceEqual(signature2)) 

:

yerine

if (signature == signature2) 

ait gibi bir şey yapabilirsiniz.

+0

evet SequenceEqual için veya karşılaştırılması dizeye dönüştürmek karşılaştırın. –

4

DSA'yı tamamen özlüyorsunuz. DSA, bir dijital imza doğrulama algoritması kullanarak doğrulamanız gereken bir imza algoritmasıdır. Aslında DSA, her kullanımda farklı bir imza üretecek şekilde tasarlanmıştır, çünkü onu oluşturmak için rastgele sayılara bağlıdır. Burada istediğiniz şey, SHA-256 veya Keccak gibi bir Karma algoritmasıdır.

+0

DSA, SHA1 karma algoritmasını kullanır, Calling '.SignData() yöntemi bir SHA1 hash değerini döndürür; ancak, eğer OP yalnızca DSH'yi yalnızca karma seçeneği için kullanıyorsa o zaman en iyi seçenek olmayabilir – geedubb

+0

@geedubb DSA SHA1 hash ama bir DSA imzası üretin. DSA, girdisini sağlamıştır ancak OP'nin gereksinimleriyle hiçbir ilişkisi yoktur. – Aris

2
Sen dosya adı ve son erişim zamanı değişmedi gerçeği itimat anlamına deciion, temel olarak

string file_information = f_info.FullName + f_info.LastAccessTime; 

kullandığınız

.

  • Sen tip FileInfo bir nesne oluştururken .NET framework dahili olarak ne yaptığını bilmiyorum. Belki de bu zaten dosyasına erişir. Veya FullName özelliğini kullanırken dosyaya erişir.
  • Aynı dosyanın özelliklerine tekrar erişirken Refresh() numaralı telefonu da aramalısınız. Aksi halde cached information kullanabilir.
  • LastAccessTime çok güvenilir değil. Performans nedenleriyle, Windows 7, işaretini bayrağını güncelleştirmez. Detaylar için "Windows Dahili 6" bölümünü okuyun.
  • Neden bu örneğinde DSA kullanıyorsunuz? Doğrudan file_information dizeleri 'u karşılaştırabilirsiniz. İmzalama ya da farketmez. Sebastian söyledi gibi
  • , byte [] eşitlik doğru