Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Colaboración Paypal con ClubDelphi

Tema Cerrado
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-05-2024
Delphier Delphier is offline
Miembro
 
Registrado: feb 2024
Posts: 42
Poder: 0
Delphier Va por buen camino
Firma Digital por DLL y XML schema binding de facturae

Hola

OS dejo mi planteamiento sobre la generación de XML y Firma por si le sirve a alguien para algo o le sirve de idea.
La idea es aplicar el sistema de Firma por DLL para Verifactu y para facturae.


1-Guardar el certificado digital y la contraseña encriptada en la base de datos

Código:
        FileStream := TMemoryStream.Create;
        FileStream.LoadFromFile(Filename); // Fichero del certificado

        TempStream := TMemoryStream.Create;
        TempStream := EncriptarStream(FileStream);

        TBlobField(Dataset.FieldByName('CertFirmaDigital')).LoadFromStream(TempStream);
2-Para firmar XML facturae y "Verifactu (Cuando se publique si es válida) "

Me acordé que hace unos años compré xmlblackbox para Delphi XE3 y no lo había usado nunca.
Se me ocurrió que para no andar comprando librerias constantemente , se podía hacer una DLL con Delphi XE3 para firmar y poder usarla con mis aplicaciones de Delphi 11, etc...

Código de la DLL con la funcion de firma en la carpeta DLLFirma y también las DLL compiladas por si sacan a alguien del paso, dejo el enlace para la descarga porque es demasiado grande para adjuntar con las DLL compiladas


h t t p s : // drive.google.com/file/d/1vrtpSGHje-l-3XW6peIGqYxHkH0g9aYx/view?usp=drive_link


Código:
// Para comprobar si un certificvado es Valido , pasando un IStream
function StreamCertificadoValido(CertStream : IStream ; Password : Pchar) : Boolean;  StdCall;

// Para comprobar si un certificvado es Valido , pasando un String con la ubicación del fichero
function FicheroCertificadoValido(Filename,Password : Pchar) : Boolean;  StdCall;

// Para firmar el XML , devuelve el XML Firmado
function FirmaFacturae(CertStream,XMLFacturae : IStream ; Password : Pchar): Pchar; StdCall;

// Para obtener cierta información del certificado (La idea final es devolver un XML con todo, pero...)
function DatoCertificado(CertStream : IStream ; Password,Dato : Pchar) : Pchar;  StdCall;
Código:
   // Ejemplos LLamada a las funciones de la DLL desde la Aplicacion   

   //Definir las funciones
   function FirmaFacturae(CertStream,XMLFacturae : IStream ; Password : Pchar): Pchar;  StdCall; external 'DLLFirmaCrt.x32.dll'; 
   function FicheroCertificadoValido(Filename,Password : Pchar) : Boolean;  StdCall; external 'DLLFirmaCrt.x32.dll' name 'FicheroCertificadoValido'; 
   function StreamCertificadoValido(CertStream : IStream ; Password : Pchar) : Boolean;  StdCall; external 'DLLFirmaCrt.x32.dll' name 'StreamCertificadoValido'; 
   function DatoCertificado(CertStream : IStream ; Password,Dato : Pchar) : Pchar; StdCall; external 'DLLFirmaCrt.x32.dll' name 'DatoCertificado';


// Firmar XML facturae con la DLL
procedure TFr_user.ButtonClick(Sender: TObject);
var Fichero,XMLString,ResultadoXML : String;
var XSendCertificadoFirma,SendXMLStream : IStream;
var XMLFileStream : TStringStream;
var TempStream : TMemoryStream;
begin


     { Fichero := 'nombre del fichero xml o directamente usar XMLString' }

     XMLString := TFile.ReadAllText(Fichero,TEncoding.Unicode);

      // Test de firma

      // El certificado
      TBlobField(Dataset.FieldByName('CertFirmaDigital')).SaveToStream(TempStream);

      // Lo desencriptamos
      XCertificadoFirma := DesencriptarStream(TempStream);

      XCertificadoFirma.Seek(0,soFromBeginning);
      XSendCertificadoFirma := TStreamAdapter.Create(XCertificadoFirma, soReference); //soOwned

     //El XMl A firmar
     XMLFileStream := TStringStream.Create(XMLString,TEncoding.Unicode);
     SendXMLStream := TStreamAdapter.Create(XMLFileStream, soReference); // Adap`tamos a IStream

     if XSendCertificadoFirma <> nil then
     Begin

      ResultadoXML := FirmaFacturae(XSendCertificadoFirma,SendXMLStream,Pchar(XCertificadoPass));

      // SI ho hay error , guardamos el fichero
      if Copy(ResultadoXML,1,7) <> '<Error>' then
      Begin
       TFile.WriteAllText(FicheroFirmado,ResultadoXML,TEncoding.Unicode);
      End
      else
      Begin
        // Error
        f_control(nil,'M',f_frase('NO SE HA PODIDO FIRMAR DIGITALMENTE LA FACTURA.',0),ResultadoXML,'');
      End;

     End
     else
     Begin
       //Showmessage('No hay certificado');
     End;


      XMLFileStream.Free;
      SendXMLStream := nil;


end;



3- Mi planteamiento de como generar el XML verifactu ya corre por este hilo.


4- Para generar el XML facturae.

Usar el esquema que proporciona la AEAT y con XML Schema Binding generar el Pas "SistemaFacturaev3_2_2.pas" , lo adjunto en la carpetas Facturae.
UFacturaE.pas es un ejemplo no terminado 100% de como se genera facilmente el XML Facturae, funciona , pero añadir cosas, solo es un ejemplo de como usar SistemaFacturaev3_2_2.pas

Saludos

---------------------------------------------------------------------------------------------------------------

NOTA DEL MODERADOR: Añado los ficheros al FTP del club (junto a la documentación), con un pequeño fichero de texto en la misma ubicación con una explicación. Y actualizo el mensaje #2 del hilo, que es el que recopila códigos.

Última edición por Neftali [Germán.Estévez] fecha: 31-05-2024 a las 11:09:40. Razón: Añado nota para os ficheros
  #2  
Antiguo 31-05-2024
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 4.215
Poder: 24
newtron Va camino a la fama
Gracias por tu aporte compañero.
__________________
Be water my friend.
  #3  
Antiguo 31-05-2024
Avatar de keys
keys keys is offline
Miembro
 
Registrado: sep 2003
Ubicación: Bilbao
Posts: 1.235
Poder: 24
keys Va por buen camino
Ayer sacaron información nueva.

https://www.agenciatributaria.es/AEA...ERI_FACTU.html

Se ha incorporado nueva documentación técnica asociada a los sistemas VERI*FACTU y no VERI*FACTU , concretamente un nuevo documento donde se detalla las especificaciones técnicas para la generación de la huella o hash de los registros de facturación y de eventos, en su versión 0.1.0 y con carácter de borrador, hasta la publicación de la Orden Ministerial definitiva.

También se ha actualizado la Documentación de descripción de servicios web en su versión 0.3.1.

NOTA DEL MODERADOR: Gracias. Actualizo el mensaje número #1 con la recopilación de información y añado el fichero al FTP del club.

Última edición por Neftali [Germán.Estévez] fecha: 31-05-2024 a las 10:28:59.
  #4  
Antiguo 31-05-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 2.764
Poder: 7
ermendalenda Va por buen camino
Cita:
Empezado por keys Ver Mensaje
Ayer sacaron información nueva.

https://www.agenciatributaria.es/AEA...ERI_FACTU.html

Se ha incorporado nueva documentación técnica asociada a los sistemas VERI*FACTU y no VERI*FACTU , concretamente un nuevo documento donde se detalla las especificaciones técnicas para la generación de la huella o hash de los registros de facturación y de eventos, en su versión 0.1.0 y con carácter de borrador, hasta la publicación de la Orden Ministerial definitiva.

También se ha actualizado la Documentación de descripción de servicios web en su versión 0.3.1.

NOTA DEL MODERADOR: Gracias. Actualizo el mensaje número #1 con la recopilación de información y añado el fichero al FTP del club.

Perfecto. Gracias
Un pasito más.
  #5  
Antiguo 31-05-2024
xevi xevi is offline
Miembro
 
Registrado: feb 2024
Posts: 69
Poder: 3
xevi Va por buen camino
Acabo de leer ese artículo y me he puesto a provar de generar el hash como dicen en el ejemplo, mi lenguaje de programación es Harbour y disponemos de la función HB_SHA256 para ese menester.
Así que lo he probado de esa manera como el Pdf para comprovar hash de ejemplos...

LogDebug( Upper(HB_SHA256( "IDEmisorFactura=89890001K&NumSerieFactura=12345678/G33&FechaExpedicionFactura=01-01-2024&TipoFactura=F1&CuotaTotal=12.35&ImporteTotal=123.45&Huella=&FechaHoraHusoGenRegistro=2024-01-01T19:20:30+01:00" )) )

LogDebug( Upper(HB_SHA256( "IDEmisorFactura=89890001K&NumSerieFactura=12345679/G34&FechaExpedicionFactura=01-01-2024&TipoFactura=F1&CuotaTotal=12.35&ImporteTotal=123.45&Huella=3C464DAF61ACB827C65FDA19F352A4E3BDC2 C640E9E9FC4CC058073F38F12F60&FechaHoraHusoGenRegistro=2024-01-01T19:20:35+01:00" )) )

Resultados:
3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60
F7B94CFD8924EDFF273501B01EE5153E4CE8F259766F88CF6ACB8935802A2B97

Correcto!!!

Así pues, a pensar en como voy a implementarlo en mi aplicación...
  #6  
Antiguo 31-05-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 2.764
Poder: 7
ermendalenda Va por buen camino
Cita:
Empezado por xevi Ver Mensaje
Acabo de leer ese artículo y me he puesto a provar de generar el hash como dicen en el ejemplo, mi lenguaje de programación es Harbour y disponemos de la función HB_SHA256 para ese menester.
Así que lo he probado de esa manera como el Pdf para comprovar hash de ejemplos...

LogDebug( Upper(HB_SHA256( "IDEmisorFactura=89890001K&NumSerieFactura=12345678/G33&FechaExpedicionFactura=01-01-2024&TipoFactura=F1&CuotaTotal=12.35&ImporteTotal=123.45&Huella=&FechaHoraHusoGenRegistro=2024-01-01T19:20:30+01:00" )) )

LogDebug( Upper(HB_SHA256( "IDEmisorFactura=89890001K&NumSerieFactura=12345679/G34&FechaExpedicionFactura=01-01-2024&TipoFactura=F1&CuotaTotal=12.35&ImporteTotal=123.45&Huella=3C464DAF61ACB827C65FDA19F352A4E3BDC2 C640E9E9FC4CC058073F38F12F60&FechaHoraHusoGenRegistro=2024-01-01T19:20:35+01:00" )) )

Resultados:
3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60
F7B94CFD8924EDFF273501B01EE5153E4CE8F259766F88CF6ACB8935802A2B97

Correcto!!!

Así pues, a pensar en como voy a implementarlo en mi aplicación...

aqui tienes tb una de las webs para comprobar los textos a sha256 para comprobar lo que generes.
https://www.convertstring.com/es/Hash/SHA256
  #7  
Antiguo 31-05-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 2.764
Poder: 7
ermendalenda Va por buen camino
Tiene pinta de que la cadena sobre la que se calcula el hash va a ser parte del QR(por la configuracio tipo parámetros dirección web), similar a ticketbai.
Con lo cual, tenedlo en cuenta para no usar caracteres extraños en la separación de número serie/numero se factura que os puedan dar conflictos con ma codificación URI para llamadas a webs. O tendréis que pasar a Uri(hexa) los caracteres que puedan dar conflictos para generar el QR
Ejemplo caracteres conflictivos:
/+:;,*<>[]\
En el caso de que lo queráis usar, simplemente es pasarlo a hexa por ejemplo el espacio es %20.., aunque el espacio no lo permiten
Pero la reprentaciob escrita(para la factura electrónica, no hay que convertirlo)
Es una pequeña traba más.

Última edición por ermendalenda fecha: 31-05-2024 a las 16:41:32.
  #8  
Antiguo 31-05-2024
Delphier Delphier is offline
Miembro
 
Registrado: feb 2024
Posts: 42
Poder: 0
Delphier Va por buen camino
Actualizo los fichero con la generación facturae ya entera y validado con el portal FACE

h t t p s://drive.google.com/file/d/1vrtpSGHje-l-3XW6peIGqYxHkH0g9aYx/view?usp=drive_link

Ficheros actulizados:
SistemaFacturaev3_2_2.pas
UFacturaE.pas
  #9  
Antiguo 02-06-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 2.764
Poder: 7
ermendalenda Va por buen camino
Cita:
Empezado por Delphier Ver Mensaje
Actualizo los fichero con la generación facturae ya entera y validado con el portal FACE

h t t p s://drive.google.com/file/d/1vrtpSGHje-l-3XW6peIGqYxHkH0g9aYx/view?usp=drive_link

Ficheros actulizados:
SistemaFacturaev3_2_2.pas
UFacturaE.pas

Hola Delphier, cuidado con las Validacionea son solo estructurales. Me ha pasado que ya me había confiado y he enviado un par de facturas por face y me la han rechazado por no coincidir importes, tenía errores de algún campo con impuesto en vez de sin impuesto...
  #10  
Antiguo 02-06-2024
Delphier Delphier is offline
Miembro
 
Registrado: feb 2024
Posts: 42
Poder: 0
Delphier Va por buen camino
Cita:
Empezado por ermendalenda Ver Mensaje
Hola Delphier, cuidado con las Validacionea son solo estructurales. Me ha pasado que ya me había confiado y he enviado un par de facturas por face y me la han rechazado por no coincidir importes, tenía errores de algún campo con impuesto en vez de sin impuesto...
Claro , hace años que generamos facturae , solo que hacía el XML a pelo , con la película de verifactu he aprovechado para cambiar la generación a "pelo" por la del esquema con XML schema binding , simplemente comparto el código de como se hace por si a alguno le interesa.

Saludos
  #11  
Antiguo 03-06-2024
Delphier Delphier is offline
Miembro
 
Registrado: feb 2024
Posts: 42
Poder: 0
Delphier Va por buen camino
Calcular Huella

Delphi 11.3

Código:
Uses System.hash

CadenaVerifactu :=
'IDEmisorFactura=89890001K&'+
'NumSerieFactura=12345679/G34&'+
'FechaExpedicionFactura=01-01-2024&'+
'TipoFactura=F1&CuotaTotal=12.35&'+
'ImporteTotal=123.45&'+
'Huella=3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60&'+
'FechaHoraHusoGenRegistro=2024-01-01T19:20:35+01:00';


 Result := THashSHA2.GetHashString(CadenaVerifactu,THashSHA2.TSHA2Version.SHA256).ToUpper;

Resultado es = F7B94CFD8924EDFF273501B01EE5153E4CE8F259766F88CF6ACB8935802A2B97
  #12  
Antiguo 03-06-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 2.764
Poder: 7
ermendalenda Va por buen camino
duda Nodo

Buenas tardes, me podrias indicar donde van los siguientes CIERRES de NODOS segun sea una anulacion o alta.
</RegistroAnulacion>
</RegistroAlta>


Va antes de <TipoHuella>01</TipoHuella>

o despues de <Huella>DEFHG...234234G</Huella>


gracias
  #13  
Antiguo 03-06-2024
Delphier Delphier is offline
Miembro
 
Registrado: feb 2024
Posts: 42
Poder: 0
Delphier Va por buen camino
Cita:
Empezado por ermendalenda Ver Mensaje
Buenas tardes, me podrias indicar donde van los siguientes CIERRES de NODOS segun sea una anulacion o alta.
</RegistroAnulacion>
</RegistroAlta>


Va antes de <TipoHuella>01</TipoHuella>

o despues de <Huella>DEFHG...234234G</Huella>


gracias

........................
<SistemaInformatico>
<IDOtro>
<CodigoPais>ES</CodigoPais>
<IDType>02</IDType>
</IDOtro>
<TipoUsoPosibleSoloVerifactu>S</TipoUsoPosibleSoloVerifactu>
<TipoUsoPosibleMultiOT>N</TipoUsoPosibleMultiOT>
<NumeroOTAlta>1</NumeroOTAlta>
</SistemaInformatico>
<FechaHoraHusoGenRegistro>2024-06-03T18:54:56.341+02:00</FechaHoraHusoGenRegistro>
<TipoHuella>01</TipoHuella>
<Huella>09E8CAFA5F83723D6D714340360D33F897329C092FD648BEA71FAD6A7D82AADE</Huella>
</RegistroAlta>
Tema Cerrado


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Hijo de Informáticos gluglu Humor 3 13-03-2007 11:05:35
Adictos informaticos ... Trigger Humor 2 11-10-2004 12:18:32
Nosotros los Informáticos Trigger Humor 1 10-10-2004 14:58:09
Patrón de los Informáticos. obiwuan Varios 20 10-09-2003 14:44:54
Chistes Informaticos jhonny Humor 2 11-08-2003 21:59:09


La franja horaria es GMT +2. Ahora son las 14:11:21.


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
Copyright 1996-2007 Club Delphi