FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#101
|
|||
|
|||
Cita:
__________________
Alejandro Jourdan |
#102
|
|||
|
|||
Problemas con el Sello
Cita:
Ya revisé la cadena y está correcta, de hecho me genera el mismo MD5 que genera el validador del SAT. Alguien ha validado los .xml con el Sello?? . Las rutinas que utilizo son las siguientes... Código:
function SelloDigital(llaveprivada, cadenaoriginal: widestring): String; var Len : cardinal; mdctx : EVP_MD_CTX; inbuf : array [0..8192] of char; outbuf : array [0..1023] of char; key: pEVP_PKEY; begin cadenaoriginal := AnsiReplaceStr(cadenaoriginal,#13,''); cadenaoriginal := AnsiReplaceStr(cadenaoriginal,#10,''); cadenaoriginal := AnsiReplaceStr(cadenaoriginal,#8,''); cadenaoriginal := AnsiReplaceStr(cadenaoriginal,' ',''); cadenaoriginal := AnsiReplaceStr(cadenaoriginal,' |','|'); cadenaoriginal := AnsiReplaceStr(cadenaoriginal,'| ','|'); cadenaoriginal := UTF8Encode(cadenaoriginal); StrPCopy(inbuf,cadenaoriginal); InitOpenSSL; key:=LoadPrivateKey(llaveprivada,''); // EVP_MD_CTX_init(@mdctx); EVP_SignInit(@mdctx,EVP_md5()); EVP_SignUpdate(@mdctx,@inbuf,Length(inbuf)); EVP_SignFinal(@mdctx,@outbuf,Len,key); // EVP_MD_CTX_cleanup(@mdctx); EVP_PKEY_free(key); FreeOpenSSL; result := bintobase64(@outbuf,Len); end; |
#103
|
|||
|
|||
¿quien de los que ya validaron tanto la estructura del xml la cadena original y el sello
puede compartir esa informacion para comparar si lo ando haciendo bien.'? gracias |
#104
|
|||
|
|||
Factura Electronica Validada en SAT
Cita:
Ya pude validar el XML completo en el Validador del SAT, la rutina que está mal es: Código:
EVP_SignUpdate(@mdctx,@inbuf,Length(inbuf)); debe ser EVP_SignUpdate(@mdctx,@inbuf,StrLen(inbuf)); Les comento que use el XML Data Binding con Delphi 7 generandolo a partir el archivo cfdv2.xsd del SAT solo requiere un truco para dar de alta los nameSpace adicionales, ya que el XML Data Binding solo puede dar de alta uno. Claro que se puede generar el XML a mano a través del XMLDocument directamente. El truco es : Código:
const // Esta cabecera es necesaria como primer renglón del archivo XML // y no se da de alta a traves del XML Data Binding. CabezaXML = '<?xml version="1.0" encoding="UTF-8"?>'; var Nodo : IXMLNode; S : String; i : integer; Cadena : wideString; begin // donde esté nuestra llave privada ya en formato .pem.... PuKey := 'C:\...\Factura Electronica\...\aaa010101aaa.cer.pem'; XMLFactura := GetComprobante(XML1); // Alta de los nameSpace faltantes... Nodo := XML1.DocumentElement; Nodo.Attributes['xmlns:xsi'] := 'http://www.w3.org/2001/XMLSchema-instance'; Nodo.Attributes['xsi:schemaLocation'] := 'http://www.sat.gob.mx/cfd/2 http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv2.xsd'; with XMLFactura do begin Version := '2.0'; ... // Generar la Cadena y luego el Sello XMLFactura.Sello := SelloDigital(PrKey,Cadena); XML1.XML.Insert(0,CabezaXML); // Generamos el archivo Fact1.XML -- cambiar el nombra al necesario. // así com el directorio de datos donde guardamos los XML XML1.Active := True; XML1.SaveToFile('C:\...\Factura Electronica\XML\Fact1.xml'); end; Saludos y mucha suerte... |
#105
|
|||
|
|||
Hola ifarias, mi solucion es muy parecida a la tuya y me permito hacerte una recomendacion.
El Data Binding del cfdv2.xsl se genera muy bien pero aveces resulta que, por ejemplo, el cliente NO tiene "Numero Interior" o "Colonia" es por eso que en la unidad cfdv2.pas te recomiendo hacer una busqueda y remplazo de : Buscar : SetAttribute( Remplazar por : if Value <> '' then SetAttribute( entonces, por ejemplo, la rutina que graba el "Numero Exterior" quedaria asi :
Eso te garantiza que no se vayan a grabar datos nulos o vacios, algo que por cierto no le gusta al validador...... Hay dos valores tipo integer, noAprobacion y anoAprobacion (sic), esos tienes que usar
Tambien me permito mostrar como yo solucione los namespace extra, algo que no me deja muy convencido de tu solucion es que creas otro nodo, rompiendo un poco con el pragma del encapsulado que te da el data binding.
|
#106
|
|||
|
|||
En el mensaje anterior estaba tratando de introducir el siguiente codigo :
XMLDoc.XML.Text := '<?xml version="1.0" encoding="UTF-8" ?><Comprobante xmlns="http://www.sat.gob.mx/cfd/2"></Comprobante>'; XMLDoc.Active := True; CFD := GetComprobante(XMLDoc); with CFD do begin SetAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance'); SetAttribute('xsi:schemaLocation','http://www.sat.gob.mx/cfd/2 http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv2.xsd'); Version := '2.0'; Serie := ...........etc.................. Pero parece que el parser no lo interpreto bien........Saludos |
#107
|
|||
|
|||
dado
Gracias por los comentarios, los tomaré en cuenta. En cuanto a generar un Nodo adicional, la realidad es que me estoy posicionando en el nodo <Comprobante> que es el raíz en ese momento, (para mi desarrollo), y agrego atributos adicionales. Esto da como resultado el siguiente código XML Código:
<Comprobante xmlns="http://www.sat.gob.mx/cfd/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/2 http://www.sat.gob.mx/sitio_internet/cfd/2/cfdv2.xsd" version="2.0" serie= .... En cuanto al XML Data Binding, tienes toda la razón, es buena idea prevenir el que se generen datos nulos, y que fácil es que cometamos errores al codificar y tener problemas posteriores. |
#108
|
|||
|
|||
Facturación eléctronica
Hola compañeros foristas
Al igual que ustedes tengo el mismo problema, ya que he desarrollado un sistema de punto de venta y algunos programas para facturación (para comercializadoras, agentes aduanales, etc.), el caso es que parece muy complicado el asunto. Entre mis desarrollos he hecho un sistema de pedimentos (sirve para elaborar documentos para importar y exportar mercancias) desde hace varios años y antes de que se presente el pedimento ante la aduana, se debe validar, para lo cual genero un archivo y este hay que firmarlo electronicamente, para lo cual en las paginas de aduana se usa un programa llamado SIFEP o se puede optar por usar unas librerias para firmalos desde tu propio programa. No sé si esto sea similar a las facturas eléctronicas, el proceso en el sistema de pedimentos es el siguiente: Pedimentos - se captura el pedimento - se genera un archivo de texto con cos datos del pedimento, importador, mercancias, etc. - Se firmar el archivo utilizando el achivo de certificado .cer y el archivo llave .key que se le ha proporcionado al agente aduanal por el SAT - La cadena resultante (firma) se agrega al final del archivo de texto que se va a validar y se imprime en el pedimento Facturación - Se captura la factura - Se genera un archivo XML con los datos del vendedor, cliente, mercancias, etc. - Se firma el archivo - Se imprime en la factura (se hace algo mas?) Al final de todo esto no sé si sea lo mismo (se puedan firmar las facturas del mismo modo) aunque sospecho que aunque se parezca no tiene nada que ver. Por lo pronto voy a empezar por estudiar como generar el XML y todo el proceso.
__________________
Cancun, Q.Roo, México |
#109
|
||||
|
||||
Que tal cancun (jeje, que nicks tan originales ),
Segun lo que comentas, el proceso es casi casi lo mismo. Adicionalmente a lo que tienes solo te restaría generar el xml y obtener su cadena de digestión y lo demás es pan comido pars ti según lo que tienes. ¿Que librerías son esas de las que dispones? Son gratis o de paga?
__________________
Tiempo y ocasión acontecen a todos! |
#110
|
|||
|
|||
Estan disponibles en la página:
http://www.aduanas.gob.mx/aduana_mex...144_10186.html Viene documentado el uso de la .dll, pero falta ver si es lo mismo, aunque al ser un formato de archivo diferente puede que no funcione. Si decides probarlo el código para usar la .dll es el siguiente: Código:
// hay que declarar al principio de tu unidad type PCURP = ^TCURP; TCURP = record curp: array[0..18] of char; archivoKey: array[0..255] of char; archivoCer: array[0..255] of char; password: array[0..18] of char end; // Declaras las funciones {$R *.DFM} function BuscaCurpsG(const archivoOrig:pchar; const tipo:Integer; struct_curps_g:PCURP):Integer; stdcall; external 'sgenc32.dll' name '_BuscaCurpsG_std@12'; function GeneraFirmaDigitalG(const archivoOrig:pchar; const tipo:Integer; struct_curps_g:PCURP):Integer; stdcall; external 'sgenc32.dll' name '_GeneraFirmaDigitalG_std@12'; // Este es el boton que ejecuta la firma procedure TFrmConfig.btnFirmarClick(Sender: TObject); var archivo: array [0..250] of Char; PReg: PCURP; Arch, Er:Integer; begin StrPCopy(archivo,FieldByName('Ruta').AsString+'\'+'m'+Patente+StrZero(Arch,3)+'.'+StrZero(DayOfTheYear(Date),3)); GetMem(PReg, SizeOf(TCURP) * 10); Er:=BuscaCurpsG(archivo, 0, PReg); StrPCopy(PReg.archivoKey,ArchivoKey); StrPCopy(PReg.archivoCer,ArchivoCer); StrPCopy(Preg.password,Clave); Er:=GeneraFirmaDigitalG(archivo, 0, PReg); if Er=0 then Mensaje('Se ha firmado correctamente el archivo: '+archivo,'Firma exitosa',mb_Ok) else MensajeError('Error al procesar la Firma: '+IntToStr(Er),'Error'); end; archivo ruta y nombre del archivo a firmar ArchivoKey Ruta y nombre del archivo con extensión .key ArchivoCer Ruta y nombre del archivo con extensión .cer Clave Password para la firma
__________________
Cancun, Q.Roo, México |
#111
|
|||
|
|||
Pues el asunto de cancun si se parece mucho a lo de la factura electronica.
Ahora, (ya estoy como en los concursos de television) cual es la pregunta? es decir, parece que tienes todo resuelto, tienes la dll, la forma de usarla dentro de Delphi y no parece muy dificil y lo mejor de todo, ya tienes un sistema de pedimentos desarrollado desde hace unos años..... En donde te atoraste? |
#112
|
|||
|
|||
Bueno, no me he atorado en nada aun pues todavía no empiezo, solo estoy investigando como va el asunto y el primer problema que encuentro es para generar el archivo XML ya que es algo nuevo para mí, en unos dias debo terminar unos pendientes y entonces me meteré de lleno en este tema y estaré dando lata por aquí.
He puesto el código que utilizo por si a alguien le interesa hacer la prueba y nos comente el resultado.
__________________
Cancun, Q.Roo, México |
#113
|
|||
|
|||
Cita:
Ya que solucionaste esto usando chilkat podrias indicarme cual metodo empleaste? aki anexo los metodos que yo emplee. saludos (codigo en vb6) Código:
'Carga del Modulo de Encriptacion RSA Dim rsa As New ChilkatRsa ' Dim success As Long 'Carga de la Llave Privada y su contraseña Dim privKey As New privateKey 'success = privKey.LoadPkcs8EncryptedFile("aaa010101aaa_CSD_01.key", "a0123456789") success = privKey.LoadPkcs8EncryptedFile(Trim(gstrRutKey), Trim(gstrPasKey)) If (success <> 1) Then MsgBox privKey.LastErrorText Exit Function End If 'Exportar llave Privada a Formato XML Dim privKeyXml As String privKeyXml = privKey.GetXml 'GetXml() success = rsa.ImportPrivateKey(privKeyXml) If (success <> 1) Then MsgBox rsa.LastErrorText Exit Function End If ' Text3 = vbNullString ' Text3.Text = privKeyXml 'Definición de Tipo de Salida (Base64) rsa.EncodingMode = "base64" 'Definicion del tipo de conversion de caracteres a "utf-8" rsa.Charset = "utf-8" rsa.ImportPrivateKey privKeyXml 'publicKey 'Proceso de Encriptación usando (cadena original digerida) y (llave privada + contraseña) Dim usePrivateKey As Long usePrivateKey =1 Dim encryptedStr As String 'metodo1: cifrando wDigest que contiene la cadena original reducida con MD5 en HEX encryptedStr = rsa.EncryptStringENC(Trim(wDigest), usePrivateKey) 'metodo2: lo emplee erroneamente ' encryptedStr = rsa.SignStringENC(Trim(wDigest), "sha-1") 'metodo2: intento que digiera y cifre en un mismo paso con el parametros de la cadena original y "md5" ' encryptedStr = rsa.SignStringENC(Trim(wCadOri), "md5") |
#114
|
|||
|
|||
cknox
No veo como estas tratando la cadena original, asegúrate de que sea correcta, como primer paso. y que sea igual a la que genera el SAT, si hay diferencias, por ahí te puedes ir. Saludos |
#115
|
|||
|
|||
La cadena original ya esta bien, la genero independiente al xml, es decir manualmente segun el anexo 20, e incluso ya compare la salida que lee el validador de el SAT contra la mía, y ya coinciden inclusive los MD5 generado.
el codigo para generar la cadena original es un poco larga, asi que demos por hecho que esta correcta, dado que la validacion la acepta: Cita:
ahora bien, regresando al uso de chilkat, si aun quieres verlo la reduccion la hago asi: Código:
Dim crypt As New ChilkatCrypt2 Dim wDigest As String ' La Salida de datos será en formato hexadecmal crypt.EncodingMode = "hex" '"base64" ' El Formato de conversión para caracteres especiales, será en "utf-8" como establece el SAT crypt.Charset = "utf-8" crypt.HashAlgorithm = "md5" Dim hashStr As String 'wCadOri es la variable que contiene la cadena original generada en otra funcion; y que introduzco en esta funcion como parametro hashStr = LCase(crypt.HashStringENC(Trim(wCadOri))) wDigest = hashStr 'contiene la cadena original digerida segun estandar SAT cuando generé el xml no inclui el valor certificado que es opcional. por lo cual en la validacion me pide el certificado(*.cer) y me genera la lectura. tengo duda si es forzoso que incluya el certificado en formato hex. Pero estoy casi seguro que el problema radica en el metodo de chilkat que empleo: EncryptStringENC(txt, usePrivateKey) SignStringENC(txt, "SHA-1"|"MD5"|"MD2"|"SHA-256"|"SHA-384"|"SHA-512" ) OpenSslSignStringENC(txt) estoy empezando a creer que debo emplear la tercera, pero parece que necesito investigar el modo de emplearla. Espero haberme explicado lo suficientemente bien. saludos y nuevamente sigo esperando comentarios NOTA DE EDICION: modifique el nombre del xml y la cadena original x contener informacion confidencial que no me pertenece. Aclaración: el codigo que empleo es una adaptacion a mis necesidades, originalmente proviene de los ejemplos que provee chilkat a sus clientes. Última edición por cknox fecha: 07-06-2010 a las 06:51:37. Razón: modificar informacion que es confidencial y no distribuible |
#116
|
|||
|
|||
exito!!!
Finalmente, despues de muchas horas, de leer codigos, referencias de cada uno de los activeX de chilkat, encontre iluminacion divina y me encontre con un tema llamado:"Duplicate openssl dgst -md5 -sign myKey.pem something.txt | openssl enc -base64 -A"
Cita:
colegas, chilkat funciona, y aunk mi codigo es vb6, se supone que es compatible con delphi como lo debio haber comprobado jourdan suerte a los demas. depues de todo cuando estudiaba mi primer lenguaje fue turbo pascal, y luego delphi |
#117
|
|||
|
|||
Addenda
Estoy usando el código publicado aquí con Delphi 2007, todo estaba bien hasta que intenté agragar una addenda a mi documento XML.
Lo hize de éste modo: CFD.Addenda := 'CADENA|ADDENDA'; Y delphi me devuelve un error: [DCC Error] Main.pas(767): E2129 Cannot assign to a read-only property Entonces lo hize de éste modo: CFD:Addenda.Text := 'CADENA|ADDENDA'; y delphi me lo genera bien, pero al validar en el SAT obtengo éste error: El sello del comprobante es válido: Se presentaron los siguientes errores al validar la estructura del comprobante \Bin\FacturaSello.xml Error: cvc-complex-type.2.3: Element 'Addenda' cannot have character [children], because the type's content type is element-only. ¿Alguién me puede orientar sobre cómo agregar la addenda sin obtener errores? |
#118
|
|||
|
|||
Saludos compañeros!
Estoy comenzando a desarrollar la facturacion electronica, no he logrado entender aun paso por paso cual es el procedimiento que pide el SAT, 1. Generar la cadena original 2. Generar xml 3. Sellar la cadena He ledio lo que pide hacienda pero no logro entender que se tiene que hacer primero, ya tengo perfectamente entendido que se necesita la key y el cer junto con la FEA, que sigue despues?. Desde ya, gracias por sus aportes! |
#119
|
|||
|
|||
Cita:
Yo tengo la "Addenda AMIS", es la que usan las empresas de Seguros como Mapfre, Zurich, Qualitas, etc etc Para que empresa estas tratando de implementar la Addenda?, hay decenas, Chedraui, Soriana, Chrysler, AMECE, Liverpool, etc etc y mas etc |
#120
|
|||
|
|||
Cita:
0. Procesas el Certificado que te da el SAT, de ahi obtienes la vigencia y el numero de serie 1. Generas el XML, con los datos de tu empresa, del cliente, de los productos o servicios y con el numero de serie del certificado y un monton de datos mas 2. A partir del XML generas la "Cadena Original" 3. La Cadena Original la digieres con MD5 4. La Digestion MD5 te arroja una cadena de caracteres hexadecimales, esta cadena la firmas usando la Llave Privada. Existen algunas librerias que hacen el paso 3 y 4 en una sola instruccion. 5. Normalmente la firma es binaria, tienes que convertirla a Base64 6. Ese sello se lo pegas al XML que generaste en el paso 1 voila....tienes tu factura digital (expresado en XML) Facil no? je je je Ya en serio, estos son los pasos, como ves si son un poco laboriosos y "obscuros". Yo ya tengo la solucion en Delphi 7. Si quieres mandame un mensaje a patrick2000@prodigy.net.mx para ver como te puedo ayudar mas. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Mexico - Como crear sellos en FACTURA ELECTRONICA.. | pcicom | API de Windows | 12 | 10-11-2012 18:46:55 |
Factura Electrónica | aig | Varios | 13 | 10-12-2010 17:12:44 |
factura electronica | cmm07 | Varios | 4 | 02-04-2009 17:46:03 |
factura electronica | spia | Varios | 2 | 22-02-2009 21:30:06 |
Factura electronica AUNA | Aprendiz | Varios | 5 | 01-09-2005 10:44:15 |
|