2015-05-07 16 views
14

Conoscendo poco della crittografia, ho grossi problemi con quello che sembra essere un compito semplice.Come verificare i dati rispetto alla firma con una chiave pubblica che utilizza sha1ecdsa?

Ho certificato .pem, byte di dati e firma di tali dati. Voglio verificare se qualcuno ha modificato i dati abbinandolo alla firma.

La mia prova:

private bool VerifySignature(byte[] data, byte[] signature) 
{ 
    try 
    { 
    X509Certificate certificate = new X509Certificate("cert_filename.pem"); 
    if (certificate == null) 
     return false; 

    DSACryptoServiceProvider dsa = (DSACryptoServiceProvider)certificate.PublicKey.Key; 

    return dsa.VerifyData(data, signatureData); 
    } 
    catch 
    { 
    return false; 
    } 
} 

Ma mi dà un errore

'algoritmo di chiave certificati non è supportato' (System.NotSupportedException).

Guardando nel certificato caricato si dice che l'algoritmo della firma è 'sha1ecdsa'.

Sto provando solo a verificare i dati contro la firma. Cosa mi manca qui? Mi piacerebbe farlo senza soluzioni esterne in quanto sembra un compito davvero banale.

Update: Sto cercando di ottenere stessa funzionalità in seguito codice Java:

private boolean verify(byte[] data, byte[] signature) 
{ 
    boolean isLicenseCorrect = false; 

    Signature sig = Signature.getInstance("SHA1WithECDSA"); 
    sig.initVerify(certificate.getPublicKey()); 
    sig.update(data); 

    return sig.verify(signature); 
} 
+0

come per ur aggiornamento se si desidera convertire il codice Java in C# [link] (http://dotnetslackers.com/articles/security/Hashing_MACs_and_Digital_Signatures_in_NET.aspx) questo potrebbe aiutare a dare un'occhiata –

risposta

6

Anche se DSA e ECDSA sono correlate, non sono la stessa cosa. Perché non provare ECDsaCryptoServiceProvider? Notare che il supporto ECDSA per le curve ellittiche include solo le curve denominate NIST.

+0

Purtroppo non posso accedere a questa classe nel mio codice Windows Form. Ho solo ECDsa e ECDsaCng, nessuno dei quali sono in grado di utilizzare. – kasper

+0

OK, quindi * perché * non riesci a utilizzare queste classi? Dovrebbero fornire un obiettivo migliore dato che 'DSACryptoServiceProvider' semplicemente non funzionerà mai. Nota che non ho il tuo setup (non sto usando Windows Form da solo, so solo cose su Crypto e quello che vedo passare qui su SO). –

+0

Come ho già detto, non so molto di crypto e non riesco a capire da solo come risolvere il mio compito. Esistono molti articoli sulla rete che utilizzano RSACryptoServiceProvider o DSACryptoServiceProvider, ma non sono riuscito a farlo funzionare con loro. – kasper

0

.NET 4.6.1 ha aggiunto il supporto migliorato per ECDSA. Mentre io non sono un fan di vostro fermo-tutto-e-ritorno-falso, lo terrò qui per il confronto:

private bool VerifySignature(byte[] data, byte[] signature) 
{ 
    try 
    { 
     // new cannot return null, so no point in a null check. It would have thrown. 

     using (X509Certificate certificate = new X509Certificate("cert_filename.pem")) 
     using (ECDsa ecdsa = certificate.GetECDsaPublicKey()) 
     using (RSA rsa = certificate.GetRSAPublicKey()) 
     // Improved DSA is 4.6.2 
     { 
      // You said the cert was ECDSA-SHA1, but that doesn't mean the original data was. 
      // I assumed it was. 
      if (ecdsa != null) 
       return ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA1); 

      if (rsa != null) 
       return rsa.VerifyData(data, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1); 

      return false; 
     } 
    } 
    catch 
    { 
     return false; 
    } 
} 

Si noti che in .NET 4.6 classe base RSA ha il segno/Verifica metodi definiti, e in 4.6.1 la classe base ECDsa ha ottenuto un trattamento simile. Il nuovo codice non dovrebbe parlare dei tipi * CryptoServiceProvider a meno che non vengano caricate chiavi con nome preesistente.

Vale anche la pena notare che i metodi Get [Algorithm] PublicKey restituiscono null quando la chiave pubblica non è di quel tipo di algoritmo, quindi è richiesto un controllo nullo.