2009-07-28 129 views
17

Estoy intentando firmar un archivo XML utilizando un certificado x.509, puedo usar la clave privada para firmar el documento y luego usar la firma CheckSignature método (tiene una sobrecarga que recibe un certificado como parámetro) para verificar la firma.En C#, firme un xml con un certificado x.509 y compruebe la firma

El problema es que el usuario que valida la firma debe tener el certificado, mi preocupación es que si el usuario tiene el certificado, entonces tiene acceso a la clave privada, y según tengo entendido, esto es privado y debería estar disponible solo para el usuario que firma.

¿Qué me estoy perdiendo?

Gracias por su ayuda.

Respuesta

5

Cualquier certificado tiene una parte pública y una parte privada. Solo envías alrededor de la parte pública. Simplemente abra cualquier sitio web con SSL habilitado en su navegador, haga clic en el símbolo del candado y eche un vistazo a su certificado.

+0

Gracias, eso es exactamente lo que no tenía claro. Ahora sé que tengo que usar un certificado de X509Store para obtener el certificado "firmante" y utilizar un archivo .cer como "verificador". – willvv

19

En .NET, Si obtiene su certificado X509 desde un archivo .pfx, así:

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

A continuación, puede exportar la parte de clave pública de este modo:

rsaCsp.ToXmlString(false); 

El " falso ", dice la parte, solo exporta la pieza pública, no exporta la pieza privada. (Doc para RSA.ToXmlString)

Y luego, en la aplicación verificación, utilice

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

Y el VerifyXml llama CheckSignature(). Se ve algo como esto:

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

El código parece ser de http://msdn.microsoft.com/en-us/library/ms229950(v=vs.110).aspx. Creo que es genial que incluyas el código aquí en lugar de simplemente vincularlo, pero dale crédito donde es debido. –

0

En primer lugar todo lo que necesita para asegurarse de que el certificado o .pfx .cer que está utilizando ha sido diseñada para la firma de propósito.

 
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** 

Una aplicación de consola completa para firmar digitalmente/verificar XmlDocument en C# se escribe here.

Cuestiones relacionadas