![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
#2
|
||||
|
||||
|
Hola johan.
Estando lejos de ser un experto en estas cosas, para la parte de la firma digital te sugiero echar un vistazo a este par de enlaces y valorar las recomendaciones que ahí se dan: http://www.clubdelphi.com/foros/showthread.php?t=61897 http://www.clubdelphi.com/foros/show...376#post416376 Por si decides usar "COM Interop", dejo aquí el código que escribí cuando necesité hacer algo muy parecido a lo que buscas (también en Delphi 7): Código:
/* FirmaXML 1.0
Ensamblaje .NET para permitir el firmado XMLDSig de un documento fiscal mexicano de formato XML.
DLL compilada con la versión de prueba de Visual Studio. */
using System;
using System.IO;
using System.Xml;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
namespace FirmaXML
{
/* Permitimos que esta clase pueda ser exportada como interfaz COM, para ser utilizada en
entornos no .NET también. */
[ComVisible (true)]
[Guid ("4EA3AB36-9DD1-42C5-B57A-D0F89DC4711B")]
public class FirmaXML
{
public string Firmar (string XML, string RFC)
{
/* Método que recibe el texto de un documento XML y regresa ese mismo texto pero conteniendo
una firma digital XMLDSig envolvente.
Parámetro XML: Texto del documento a firmar.
Parámetro RFC: RFC del contribuyente cuyo certificado se usará para la firma. */
// Obtenemos el certificado correspondiente al RFC dado
X509Certificate2 Certificado = BuscarCertificado (RFC);
// Obtenemos el objeto de llave privada del certificado
RSACryptoServiceProvider Llave = Certificado.PrivateKey as RSACryptoServiceProvider;
// Creamos el objeto firmante (Firma) asignándole el texto XML y la llave del certificado
XmlDocument Documento = new XmlDocument ();
Documento.LoadXml (XML);
SignedXml Firma = new SignedXml (Documento);
Firma.SigningKey = Llave;
/* Creamos el nodo <Reference> con un subnodo <Transforms> conteniendo el elemento
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />, y lo
agregamos al objeto firmante */
Reference Referencia = new Reference ();
Referencia.Uri = ""; // Tomar ("digerir") todo el documento al crear la firma
Referencia.AddTransform (new XmlDsigEnvelopedSignatureTransform ());
Firma.AddReference (Referencia);
/* Creamos el nodo <KeyInfo> con el subnodo <X509Data>, poniendo dentro de éste el
certificado, su número de serie y la entidad emisora del mismo (primero estos dos últimos
como subnodo <X509IssuerSerial>), y agregando todo al objeto firmante. */
KeyInfoX509Data NodoX509Data = new KeyInfoX509Data ();
NodoX509Data.AddIssuerSerial (Certificado.Issuer, Certificado.GetSerialNumberString ());
NodoX509Data.AddCertificate (Certificado);
Firma.KeyInfo = new KeyInfo ();
Firma.KeyInfo.AddClause (NodoX509Data);
// Generamos la firma digital y la agregamos al objeto Documento
Firma.ComputeSignature ();
Documento.DocumentElement.AppendChild (Documento.ImportNode (Firma.GetXml (), true));
// Devolvemos el XML firmado
return Documento.OuterXml;
}
protected static X509Certificate2 BuscarCertificado (string RFC)
{
// Método para obtener el certificado que pertenece a un RFC
// Cargamos la lista de certificados personales instalados en Windows
X509Store Certificados = new X509Store (StoreName.My, StoreLocation.CurrentUser);
Certificados.Open (OpenFlags.ReadOnly);
// Buscamos el certificado del contribuyente
foreach (X509Certificate2 Resultado in Certificados.Certificates)
/* El sujeto (propiedad Subject) del certificado puede contener algo como:
"OU=Unidad 1, SERIALNUMBER=" / AAAA010101HDFRXX01", " (continúa)
"OID.2.5.4.45=AAA010101AAA / AAAA010101AAA, O=Matriz SA, " (continúa)
"OID.2.5.4.41=Matriz SA, CN=Matriz SA"
"AAA010101AAA / AAAA010101AAA" son el RFC del contribuyente (persona moral o física) y,
opcionalmente, el RFC de la persona física que representa a la persona moral
(posiblemente). El primero es el que nos interesa y debe ser igual al parámetro RFC para
dar por encontrado el certificado.
Revisaremos cada par "llave=valor" del sujeto. NOTA: Puede que convenga robustecer el
código de este ciclo anidado. */
foreach (string Dato in Resultado.Subject.Split (','))
{
string[] LlaveValor = Dato.Trim().Split ('=');
if ((LlaveValor.Length == 2) && LlaveValor [0].EndsWith ("2.5.4.45") &&
(LlaveValor [1].Split ('/') [0].Trim () == RFC))
return Resultado; // Encontrado
}
throw new Exception ("No hay un certificado instalado para el RFC que se indicó.");
}
}
}
Lo mejor de todo es que funcionó, quedándome con una grata impresión de las bibliotecas nativas de .NET (lástima que su lenguaje puntero sea un derivado de C ).Ojalá pueda servirte como base a ti o alguien más. ![]() Saludos. Al González. |
|
|
Temas Similares
|
||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| Firmar xml digitalmente. | BuenaOnda | Varios | 2 | 21-10-2010 11:13:46 |
| Firmar PDF | keys | Varios | 1 | 06-05-2010 10:11:37 |
| Firmar archivos XML | chipsoni | Seguridad | 4 | 27-11-2008 11:53:37 |
| Firmar PDF | j_fdez | Varios | 1 | 02-04-2008 15:16:18 |
| firmar ActiveX | coulthard | Internet | 0 | 22-01-2005 18:58:55 |
|