Este es el codigo con el que recuerdo hice las pruebas de firmado de un XML (xml signature), fue para un proyecto de Brasil (donde se firmar todo el XML no solo la cadena original)
En mis pruebas recuerdo que la firma salia igual a la de un proveedor de factura electronica de Brasil. Pero ojo.. no fue VB6, fue .net, lo de menos seria generar una DLL que se importara desde VB6
Código: Seleccionar todo
protected void BtnUpload_Click(object sender, EventArgs e)
{
//BtnUploadF FIRMAR DOCUMENTO
try
{
//Cargamos el documento en el XmlDocument
XmlDocument doc = new XmlDocument();
//doc.PreserveWhitespace = true;//Preservamos los espacios CAMBIA EL DIGEST VALUE!!! (deja 10K)
doc.PreserveWhitespace = false;//Preservamos los espacios
Stream stm = FileUpload1.PostedFile.InputStream;
doc.Load(stm);
X509Certificate2 cetificado = ObtenerCertificado(DDListCertifi.SelectedItem.Text);
FirmarXML(ref doc, cetificado);
doc.Save(Server.MapPath(".") + "\\Firmado_" + FileUpload1.FileName);
HLinkDoc.Text = "Ver Documentó Firmado.";
HLinkDoc.NavigateUrl = "Firmado_" + FileUpload1.FileName;
HLinkDoc.Visible = true;
lblMsg.Text = "Documentó Firmado.";
}
catch (Exception ex)
{
lblMsg.Text = "Error en la Firma!!!.<br>(" + ex.Message + ")";
}
}
/// <summary>
/// Firma el documento
/// </summary>
/// <param name="documento">Documento XML</param>
/// <param name="certificado">Certificado</param>
private static void FirmarXML(ref XmlDocument documento, X509Certificate2 certificado)
{
// 1.- Se Carga el XML dentro de la clase signedXML
SignedXml sig = new SignedXml(documento);
//2.- Recuperamos la clave privada para firmar
// Obtenemos el certificado digital del almacén de certificados (obtenemos el certificado con
// el Canonical Name contenido en el parámetro subjectName), y como vamos a realizar una firma,
// introducimos la clave privada del certificado en .SigningKey
sig.SigningKey = certificado.PrivateKey;
// de JAGP
//3.- Add a KeyInfo.
//Para dar la posibilidad al receptor de comprobar la firma sin necesidad de tener el certificado,
//introducimos la clave pública del certificado dentro de la propiedad .KeyInfo.
//Como referencia y de manera opcional, introducimos el Canonical Name del certificado.
// KeyInfo keyInfo = new KeyInfo();
//////keyInfo.AddClause(new DSAKeyValue(objDSAkeyPair));
// keyInfo.AddClause(new KeyInfoX509Data(certificado));
// sig.KeyInfo = keyInfo;
//3. Add public key info to allow checking the key
sig.KeyInfo = new KeyInfo();
KeyInfoX509Data keyInfoClause = new KeyInfoX509Data(certificado);
//keyInfoClause.AddSubjectName(certificado.SubjectName.Name); // Con las siguientes instrucciones se agregaria tambien el X509SubjectName
sig.KeyInfo.AddClause(keyInfoClause);
//4. Set the reference to sign
//http://www.devarch.net/post/2010/01/29/Firmar-un-documento-Xml-con-SignedXml.aspx
// Como no deseamos firmar el documento Xml entero, sino el nodo acuses,
// introducimos el valor de su atributo id (viene contenido en el parámetro nodeToSign
// con valor “#response”) como referencia. En nuestro caso, ya que vamos ah hacer
// una firma Enveloped, es necesario firmar un nodo en lugar del Xml completo porque sino,
// no se podría luego validar la firma.
//(Para firmar el documento completo, reference.Uri ha de ser una cadena vacía).
Reference reference = new Reference();
//No le asignamos ninguna Url en concreto al querer firmar todo el doc.
reference.Uri = "#NFe4306039266561101315555099000006996000579519";
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); //parametro true o false??
// de JAGP
Transform transform = new XmlDsigC14NTransform(false); // incluir comentarios True, False
//Transform transform = new XmlDsigC14NTransform(true); // cambia el signature value
//-------------------------
// Esta combinacion deja OK la Diges y Signature Value pero con 14Kb.. y NO PASA LA VALIDACION
//doc.PreserveWhitespace = false
//Transform transform = new XmlDsigC14NTransform(false)
//Añadimos la transformación a la referencia
reference.AddTransform(env);
reference.AddTransform(transform);
sig.AddReference(reference);
// Si coloco aqui la 2a transform cambia la signature value
// reference.AddTransform(transform);/////
// sig.AddReference(reference);/////
//5. Compute the signature Calculamos la firma.
sig.ComputeSignature();
//6. Append node to the document
//Introducimos el Xml con la firma dentro del documento Xml.
XmlElement xmlDigitalSignature = sig.GetXml();
documento.DocumentElement.AppendChild(documento.ImportNode(xmlDigitalSignature,true)); // boolean deep
// DIGEST VALUE CORRECTO: bjdJWunzyN8Saf+e6joIlt7uvhc=
// SIGNATURE: H0erTiulPNBaRdiIclOA+PjZkz4lIuiALpQ1/jybb2roM1jtazkjulsGxOZfsoZL/ZtlMPTDQkG6P9zqmcEYRhbVhSM0tj2xEmbUFDOq6JwZWsTD3pQB4q++rviiqjlNisrCruLsCvQjSAbPVZvST9iE2rRV4V59voG09ho8hHg=
}
/// <summary>
/// Verifica la firma de un documento
/// </summary>
/// <param name="documento">Documento XML</param>
/// <param name="certificado">Certificado</param>
/// <returns></returns>