Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Pasar de C# a Delphi (https://www.clubdelphi.com/foros/showthread.php?t=94356)

gasal 22-12-2019 13:06:07

Pasar de C# a Delphi
 
Saludos Compañeros.

No conozco de C# y hacienda efectuo este ejemplo para firmar xml de facturacion electronica.
Me pueden ayudar a pasarlo a Delphi ?

Desde ya muchas gracias.

Cita:

(El siguiente ejemplo es una aplicación de consola desarrollada utilizando Visual Studio express 2013 for desktop.
En su método Main, carga el archivo xml a cifrar y el certificado desde el archivo del almacén de certificados,
suponiendo que ambos se encuentran en el directorio de la aplicación.
La ejecución sigue de la siguiente manera:
Se selecciona el elemento del documento que se va a cifrar
Se cifra el elemento y se guarda el xml obtenido
Se vuelve a cargar el documento cifrado desde el archivo recientemente guardado.
Se descifra el documento y se guarda con un nuevo nombre. Este documento debería ser
igual al documento inicial.
Para poder ejecutar el ejemplo se debe crear una nueva aplicación de consola y agregar una
referencia (Add Reference…) y seleccionamos el “assembly” System.Security.
Sustituir el contenido del archivo Program.cs por el siguiente código (recordar que se debe cambiar el
nombre del archivo xml original, el del almacén de certificados y la contraseña, por los correspondientes en su ambiente, el xpath del nodo a
cifrar podría ser diferente según el documento utilizado).
Se debe utilizar como algoritmo asimétrico rsa-pkcs1 (http://www.w3.org/2001/04/xmlenc#rsa-1_5) y como algoritmo simétrico: 3DES-CBC (http://www.w3.org/2001/04/xmlenc#tripledes-cbc).
Finalmente como nombre de clave (KeyName) se debe utilizar CERT_DGI_EFACTURA.)
Código:

using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Security.Cryptography.Xml;
 using System.Security.Cryptography.X509Certificates;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
 using System.Security.Cryptography;
 namespace DgiEncriptarXml {
 class Program {
 / <summary>
 / Lee y escribe todos los archivos desde el directorio de la aplicación.
 / </summary>
 / <param name="args"></param>
 static void Main(string[] args) {
 const string NOMBRE_CLAVE = "CERT_DGI_EFACTURA";
 / Se carga el documento a cifrar
 var xmlDoc = CargarXml(@"EnvioCfe_net_sin_encriptar.xml");
 / Se carga el certificado que se va a utilizar.
 / Se utiliza la clave pública para cifrar y la clave privada para descifrar
 var cert = CargarCertificado("client.p12", "secreto");
 / Se selecciona el nodo del documento que se cifrará
 var xmlNM = new XmlNamespaceManager(xmlDoc.NameTable);
 xmlNM.AddNamespace("ns0", "http://cfe.dgi.gub.uy");
 var elm =
 xmlDoc.SelectSingleNode("/ns0:EnvioCFE/ns0:CFE/ns0:eFact/ns0:Compl_Fiscal/ns0:Compl_Fiscal_Data", xmlNM) as XmlElement;
 
 /Encriptamos
 EncriptarXml(elm, cert, NOMBRE_CLAVE);
 /Guardo el documento cifrado
 xmlDoc.Save("EnvioCfe_net_encriptado.xml");
 /Cargo nuevamente el documento cifrado
 xmlDoc = CargarXml("EnvioCfe_net_sin_encriptar.xml");
 / Se descifra el documento
 DesencriptarDocumento(xmlDoc, cert, NOMBRE_CLAVE);
 /Guardo el documento descifrado
 xmlDoc.Save("EnvioCfe_net_desencriptado.xml");
}

/ <summary>
/ Carga un certificado desde un almacén tipo #PKCS12
/ El certificado podría cargarse desde otros lugares,
/ por ejemplo, el almacén de windows
/ </summary>
/ <param name="path">Camino al archivo</param>
/ <param name="contrasenia">Contraseña del almacén</param>
/ <returns></returns>
private static X509Certificate2 CargarCertificado(string path, string contrasenia) {
 return new X509Certificate2(path, contrasenia, X509KeyStorageFlags.Exportable);
}
/ <summary>
/ Carga el documento xml que contiene el nodo a cifrar
/ </summary>
/ <param name="path">Camino al archivo</param>
/ <returns></returns>
private static XmlDocument CargarXml(string path) {
 var xmldoc = new XmlDocument();
 xmldoc.PreserveWhitespace = false;
 xmldoc.Load(path);
 return xmldoc;
}

 / <summary>
 / Cifra el nodo utilizando la clave pública del certificado suministrado.
 / </summary>
 / <param name="nodoParaEncriptar">Elemento para cifrar</param>
 / <param name="cert">Certificado </param>
 / <param name="nombreClave">Nombre para la clave</param>
 private static void EncriptarXml(XmlElement nodoParaEncriptar, X509Certificate2 cert, string
 nombreClave) {
 / Se crea una nueva clave TripleDES.
  TripleDESCryptoServiceProvider tDESkey = new TripleDESCryptoServiceProvider();
 / Se crea una nueva instancia de EncryptedXml y la uso para encriptar el elemento con la clave simétrica.
 EncryptedXml eXml = new EncryptedXml();
 byte[] encryptedElement = eXml.EncryptData(nodoParaEncriptar, tDESkey, false);
 
 / Se construye el objeto EncryptedData y se carga la información de cifrado deseada
 EncryptedData edElement = new EncryptedData();
 edElement.Type = EncryptedXml.XmlEncElementUrl;
 edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncTripleDESUrl);
 var alg = (RSACryptoServiceProvider)cert.PublicKey.Key;
 / Se cifra la clave simétrica.
 EncryptedKey ek = new EncryptedKey();
 byte[] encryptedKey = EncryptedXml.EncryptKey(tDESkey.Key, alg, false);
 ek.CipherData = new CipherData(encryptedKey);
 ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
 /Agrega la clave cifrada al objeto EncriptedData
 edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
 
 / Asigna el Elemento KeyInfoName para especificar el nombre de la clave RSA
 KeyInfoName kin = new KeyInfoName();
 kin.Value = nombreClave;
 / Agrega el KeyInfoName al objeto encriptado
 ek.KeyInfo.AddClause(kin);
 edElement.CipherData.CipherValue = encryptedElement;
 EncryptedXml.ReplaceElement(nodoParaEncriptar, edElement, false);
 }
 / <summary>
 / Descifra el documento utilizando la clave privada del certificado suministrado
 / </summary>
 / <param name="xmlDoc">Documento a descifrar</param>
 / <param name="cert">Certificado a utilizar</param>
 / <param name="nombreClave">Nombre de la clave simétrica</param>
 private static void DesencriptarDocumento(XmlDocument xmlDoc, X509Certificate2 cert, string
 nombreClave) {
 EncryptedXml exml = new EncryptedXml(xmlDoc);
 / Agrega el diccionario clave-nombre
 / Este método sólo puede descifrar documentos
 / que contengan la clave especificada
  var privateKey =(RSACryptoServiceProvider)cert.PrivateKey;
 exml.AddKeyNameMapping(nombreClave, privateKey);
 
 / Descifrar el elemento.
 exml.DecryptDocument();
  }
  }
 }


Al González 24-12-2019 02:56:15

Hola gasal.

No sé a qué país te refieres con hacienda, pero con tu mensaje recordé un caso similar que puedes consultar a través de este par de enlaces:

http://rescatandoadelphi.blogspot.co...go-delphi.html

http://www.clubdelphi.com/foros/showthread.php?t=77783

No te garantizo que te lleven a solucionarlo pronto, pero quizá te sean de alguna utilidad.

Un saludo.

Al González.


La franja horaria es GMT +2. Ahora son las 20:03:53.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi