17

Sto provando a firmare un file XML usando un certificato x.509, posso usare la chiave privata per firmare il documento e quindi usare la firma di controllo metodo (ha un sovraccarico che riceve un certificato come parametro) per verificare la firma.In C#, firma un xml con un certificato x.509 e controlla la firma

Il problema è che l'utente che convalida la firma deve avere il certificato, la mia preoccupazione è, se l'utente ha il certificato allora ha accesso alla chiave privata e, come ho capito, questo è privato e dovrebbe essere disponibile solo per l'utente che firma.

Cosa mi manca?

Grazie per il vostro aiuto.

risposta

5

Qualsiasi certificato ha una parte pubblica e una privata. Tu mandi solo in giro per la parte pubblica. Basta aprire qualsiasi sito Web abilitato SSL nel browser, fare clic sul simbolo del lucchetto e dare un'occhiata al loro certificato.

+0

Grazie, è esattamente quello che non avevo chiaro. Ora so che devo usare un certificato da X509Store per ottenere il certificato "firmatario" e utilizzare un file .cer come "verificatore". – willvv

19

In .NET, se si ottiene il cert X509 da un file pfx, in questo modo:

X509Certificate2 certificate = new X509Certificate2(certFile, pfxPassword); 
RSACryptoServiceProvider rsaCsp = (RSACryptoServiceProvider) certificate.PrivateKey; 

Quindi è possibile esportare la parte di chiave pubblica in questo modo:

rsaCsp.ToXmlString(false); 

Il " false "parte dice, esportare solo il pezzo pubblico, non esportare il pezzo privato. (Doc per RSA.ToXmlString)

E poi nell'applicazione la verifica, utilizzare

RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
csp.FromXmlString(PublicKeyXml); 
bool isValid = VerifyXml(xmlDoc, rsa2); 

E il VerifyXml chiama CheckSignature(). Sembra qualcosa di simile:

private Boolean VerifyXml(XmlDocument Doc, RSA Key) 
{ 
    // Create a new SignedXml object and pass it 
    // the XML document class. 
    var signedXml = new System.Security.Cryptography.Xml.SignedXml(Doc); 

    // Find the "Signature" node and create a new XmlNodeList object. 
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature"); 

    // Throw an exception if no signature was found. 
    if (nodeList.Count <= 0) 
    { 
     throw new CryptographicException("Verification failed: No Signature was found in the document."); 
    } 

    // Though it is possible to have multiple signatures on 
    // an XML document, this app only supports one signature for 
    // the entire XML document. Throw an exception 
    // if more than one signature was found. 
    if (nodeList.Count >= 2) 
    { 
     throw new CryptographicException("Verification failed: More that one signature was found for the document."); 
    } 

    // Load the first <signature> node. 
    signedXml.LoadXml((XmlElement)nodeList[0]); 

    // Check the signature and return the result. 
    return signedXml.CheckSignature(Key); 
} 
+2

Il codice sembra provenire da http://msdn.microsoft.com/en-us/library/ms229950(v=vs.110).aspx. Penso che sia bello che tu includa il codice qui invece di limitarti a collegarti ad esso, ma dare credito dove è dovuto. –

0

Prima di tutto è necessario essere sicuri che il .pfx certificato o cer che si sta utilizzando è destinato per la firma scopo.

 
You can check same in General Tab of a certificate 

*.Proves your identity to a remote computer 
*.Protects e-mail messages 
*.Allows data to be signed with the current time 
*.Allows data on disk to be encrypted 
*.2.16.356.100.2 
**Document Signing** 

un'applicazione completa console per firmare digitalmente/verificare XmlDocument in C# è scritto here.