
28/03/2011 17:53 por
zorry
En el anterior artículo he introducido el concepto de la firma digital mediante los estándares XAdES y XML-DSig. En este artículo vamos a ver cómo validar una firma mediante XML-DSig, empleando las clases nativas facilitadas en .Net, en modo Enveloped, así como vamos a generar un certificado X509 para poder realizar la firma y ver cómo accedemos al mismo.
Para realizar esta firma vamos a utilizar un certificado de usuario. Un certificado de usuario válido puede ser cualquiera de los expedidos por entidades certificadoras como por ejemplo la Fábrica Nacional de Moneda y Timbre. Para hacer este pequeño ejemplo, emplearemos un certificado de pruebas generado en .Net, tomando como referencia las instrucciones que indico en este artículo. Del mismo artículo podemos tomar el método para recuperar un objeto X509Certificate2 con el contenido del certificado digital.
Primero vamos a escribir un método que nos permita realizar una validación de una firma empleando el objeto SignedXml. Este método podrá validar cualquier XML con firma Enveloped, ya que la clave pública con la que está firmado el XML debería estar presente en el nodo Signature del XML.
public void Validate(XmlDocument document)
{
XmlNamespaceManager nsMgr = new XmlNamespaceManager(document.NameTable);
nsMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
//Cargamos el XML en el objeto SignedXML
SignedXml verifier = new SignedXml(document);
//Obtenemos el nodo de la firma y se lo porporcionamos al objeto SignedXml para poder realizar la validación
XmlElement signatureElement = document.DocumentElement.SelectSingleNode("//ds:Signature", nsMgr) as XmlElement;
verifier.LoadXml(signatureElement);
//Realizamos la comprobación
if (!verifier.CheckSignature())
throw new InvalidSignatureException();
}
Generaremos el certificado de pruebas con la siguiente sentencia, para crearnos un certificado en la carpeta Personal del almacén de certificados del usuario que ha iniciado la sesión:
makecert -sr CurrentUser -ss My -a sha1 -n CN=TestCertificate,OU=Testing,OU=local -sky exchange –pe
Lo podremos ver si accedemos a Internet Explorer, abrimos las Opciones de Internet, vamos a la pestaña Contenido y pulsamos el botón Certificados…

Tengamos en cuenta que este certificado sólo nos va a valer para hacer pruebas en la máquina local, si necesitamos hacer pruebas en varias máquinas tendremos que o bien instalar este mismo certificado en ellas, o bien instalar un certificado válido.
Para poder emplear este certificado, modificamos el método para obtener el certificado para que realice la carga del mismo desde el almacén de certificados del usuario:
public X509Certificate2 GetCertificateFromStore(StoreLocation storeLocation,
StoreName storeName, string thumbprint)
{
X509Store store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs =
store.Certificates.Find(X509FindType.FindByThumbprint,
thumbprint, false);
store.Close();
return certs[0];
}
Si hiciéramos una prueba unitaria de este método podríamos comprobar como efectivamente recuperamos el certificado de usuario:
[TestMethod]
public void TestGetCertificate()
{
Signature sig = new Signature();
X509Certificate2 cert = sig.GetCertificateFromStore(StoreLocation.CurrentUser, StoreName.My,
"91 15 78 ac 78 8a 20 4d e2 33 96 4a c7 90 c1 36 c0 db ad df");
Assert.IsNotNull(cert);
}
Para acceder al certificado empleamos la propiedad Thumbprint (Huella dactilar) del mismo, que podemos ver en las propiedades del certificado:

En el próximo artículo realizaremos una firma con SignedXml y el certificado recuperado.
e00eb190-02f3-4303-a2b5-238806da188e|2|4.5