none
Firmar XML facturae con signedXml RRS feed

  • Pregunta

  • Viendo que es casi imposible hacer esto en .net, ¿Como puedo utilizar las librerias que da la agencia tributaria desde vb .NET?, es decir, ya tengo todo el código que me genera el xml con formato facturae, como puedo añadirle la firma con lo de java.

    Muchas gracias
    martes, 28 de abril de 2009 16:28

Todas las respuestas

  • DiegoDGS podrias ser tan amable de enviarme el codigo en .net que genera el xml en formato facturae, yo tengo algo parecido pero me falla al generar la factura.

    Gracias
    miércoles, 29 de abril de 2009 6:29
  • Hola, de casualidad has podido avanzar con este tema? Estoy en el mismo punto que tú.
    Gracias.
    miércoles, 27 de mayo de 2009 16:03
  • Hola, me he quedado estancado. He podido firmar con el certificado, pero no la parte XADES, micorsoft todabía no la tiene implemantada en el framework, solo he conseguido esta estructura:

    <ds:Signature >
       <ds:SignedInfo/>
       <ds:SignatureValue/>
       <ds:KeyInfo>
          <ds:X509Data>
             <ds:X509Certificate/>
          </ds:X509Data>
       </ds:KeyInfo>
    </ds:Signature>

    Me falta poder completar hasta:

    <ds:Signature >
       <ds:SignedInfo/>
       <ds:SignatureValue/>
       <ds:KeyInfo>
          <ds:X509Data>
             <ds:X509Certificate/>
          </ds:X509Data>
       </ds:KeyInfo>
       <ds:Object>
          <xades:QualifyingProperties>
             <xades:SignedProperties>
                <xades:SignedSignatureProperties>
                   <xades:SigningTime />
                   <xades:SigningCertificate/>?
                   <xades:SignaturePolicyIdentifier/>
                   <xades:SignerRole/>?
                </xades:SignedSignatureProperties>
             </xades:SignedProperties>
             <xades:UnSignedProperties/>
          </xades:QualifyingProperties>
       </ds:Object>
    </ds:Signature>

    Ahora le he encargado a un coleguilla que me haga algo con las apis de JAVA que te proporcionan en la agencia tributaria, porque no hay manera, y además no hay nadie que lo haya resuelto o no suelta prenda.

    Un saludo, a ver si entre todos conseguimos algo.
    jueves, 28 de mayo de 2009 18:23
  • Gracias por contestar.

    Yo también estoy intentando averiguar como puedo conectar la aplicación .Net con otra en java que únicamente firme el documento utilizando las apis de la aeat, porque está claro que con .net no es posible.

    Si llego a averiguar o adelantar algo sobre el tema, te mantendré informado.

    Saludos.

    viernes, 29 de mayo de 2009 10:26
  • Hola,

    Después de haber pasado más de 3 meses buceando por la web para encontrar una solución para facturaE, XADES, etc, desde .NET y estar ya embarcado en intentar aprovechar las APIS de java de la aeat...

    TACHAAANN!!!!!!!

    Microsoft publica un plugin para Word 2007 GRATUITO, que permite trabajar con FacturaE v3.1, XADES-EPES, XADES-XL. Sí, sí, así como suena..
    Genera, firma y envía facturas en formato FacturaE, permite asímismo importar xml con formato facturae, etc, etc..
    Además y según comentan, han dejado el código abierto para que cada cual pueda adaptarlo a sus necesidades. Todavía no lo he estudiado, pero he encontrado por ahí un "Xades.dll" bastante apetecible..
    Se puede descargar desde aquí:  http://factoffice.codeplex.com/

    Y ya como última referencia a tener en cuenta (no sé hasta qué punto porque acabo de descubrirla) echad un vistazo a la web de facturae.es porque acaban de anunciar la publicación del nuevo formato FacturaE v3.2 !!!!   

    Saludos y espero que esto le sirva a alguien.
    miércoles, 3 de junio de 2009 15:14
  • Hola,

         Por fin se va viendo algo de color, voy yo también a investigar el tema a ver si logro hacer algo con XADES.dll, aunque me da la impresión que solo es para validar firmas.

    Pronto veremos la luz definitiva, jejejee.

    miércoles, 3 de junio de 2009 15:55
  • Perfecto, ya hay algo, a ver si conseguimos hacer algo que quede majo.

    Podiamos hacer un pequeño grupo de trabajo para crear un programa en vb.net que creara el XML y luego lo firmara (sea con esta dll o con la api de java) y luego publicar el codigo o los archivos para todos.

    Yo no he encontrado informacion de esto en ningun lado, o es en JAVA o no hay nada.

    Yo tengo un programa que genera el XML (con el XSD de la version 3.1) hasta el apartado Invoices (ahi me da un error, y no se porque) el que lo quiera, que me lo diga y se lo paso.

    A ver si entre todos conseguimos hacer un programa que genere y firme.

    Saludos
    miércoles, 3 de junio de 2009 16:25
  • Bueno por fin pude generar el XML perfectamente en formato FacturaE 3.1, pasando validacion de esquema y contable.

    De la firma habeis averiguado algo???

    Es lo unico que me queda para cerrar el proyecto en vb.net, ya me da igual firmarlo con codigo de .net o con la api de la aeat en java, lanzar ese java desde .net simplemente para que haga la firma en el XML ya generado.

    Alguien lo ha conseguido?

    Gracias
    lunes, 15 de junio de 2009 9:17
  • Buenas, justamente estoy en el proceso de generar una clase .net a partir del xsd de la facturae y nos encontramos con que nos da errores al generar el xml. En el punto que se encalla es en el de ds:Signature .

    Utilizamos para ello la herramienta xsd.exe mediante la consola de visual studio. Nos podrias decir como has conseguido que te genere el xml por favor?

    Por otra parte para el tema de cifrar mira si te sirve esto que encontré en otro foro:

    La clase XpsDocument de WPF tiene un metodo que permite firmar digitalmente
    el documento con un certificado X509Certificate, tienes la documentación en
    este enlace:

    http://msdn.microsoft.com/es-es/library/ms591644.aspx

    para ficheros XML:

    http://msdn.microsoft.com/es-es/library/ms229745(VS.80).aspx


    Gracias, saludos.

    jueves, 2 de julio de 2009 10:13
  • En la web de http://www.gtfacturae.com tienes la solución, se trata de una libreria para .net que es capaz de leer, cargar , firmar y validar facturas electronicas en los formatos facturae 3.0-3.1-3.2.



    Un saludo
    lunes, 6 de julio de 2009 16:33
  • Yo tengo el código necesario para crear una facturae en xml, compatible con la última versión.
    Sin embargo, también me falta la firma. La documentación que encuentro es escasa y llena de referencias, con lo cual me paso el día saltando de una página en otra sin concretar la solución.
    Si alguién dispone de una documentación adecuada sobre la firma que la facilite en el foro.
    Una vez finalizada mi librería me comprometo a publicarla gratuitamente.

    Un saludo.
    Mario64: The Best Game ever
    miércoles, 8 de julio de 2009 17:39
  • Mario, Buenas tardes

    Te he dejado un ejemplo de como firmar un documento XML con mi libreria GTFacturae. Puedes obtenerlo  Aqui Se trata de una solución de MS Visual Studio 2005,cuando descomprimas la solución, en el directorio Libs te he dejado la libreria GTFacturae.dll , tendras que añadir una referencia a esta dll en tu proyecto, solo vas a poder firmar con el certificado que te envio, ya que esta es la version demo de la libreria.

    El codigo no tiene mucho que comentar:

                //Si selecciona el archivo
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    //Es un archivo que existe..
                    if (System.IO.File.Exists(openFileDialog1.FileName))
                    {
                        //Ruta donde esta el certificado firmante
                        string strPathCertificado = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                        strPathCertificado+="\\cert_demo.p12";

                        //Instanciamos contenedor
                        Facturae facturae = new Facturae();
                        //Cargamos el certificado
                        facturae.LoadCertificado(strPathCertificado, "1111");
                        //Firmamos el documento
                        facturae.Firmar(openFileDialog1.FileName);
                        //limpiamos object
                        facturae = null;
                    }  
                }


    Una vez firmada la factura puedes ir al validador del ministerio http://www11.mityc.es/FacturaE/ y comprobar la firma.
    Te debería salir el siguiente mensaje:
    **El certificado firmante no está recogido en los apartados a) ó c) del artículo 18 del Reglamento que está recogido en R.D. 1496/2003 del 28 de Noviembre
    Política inválida: Política de Firma FacturaE v3.1

    Esto es porque el certificado que te adjunto no es  válido para firma  electronica de factura, este  debería ser el emitido por la FMNT ( Fabrica de moneda y timbre) o alguna autoridad de certificación reconocida, entonces la firma seria completamente válida.

    Ah! Y sin tener que instalar Office 2007 ni historias raras, una dll normalita como las de toda la vida.

    Si tienes alguna duda comentamelo.

    Un saludo y muchas gracias.
    miércoles, 8 de julio de 2009 18:19
  • Muchísimas gracias, esto va progresando muy bien. Lo único de la dll esta de GTFacturae es que necesitas una licencia por cada clave de firma, y la licencia vale 300€, es demasiado para incluirla en una aplicación para su distribución, ya que hay que sumarle el coste de 300€ por instalación, mucha tela.
    jueves, 9 de julio de 2009 7:29
  • Esta clarisimo, yo he hecho un pequeño programita en JAVA, que firma y valida, segun los parametros que le pongas.

    Lanzas ese programa con los parametros desde tu aplicación en VB y a correr.

    Facil, sencillo y para toda la familia.
    jueves, 9 de julio de 2009 7:40
  • Diego, Tienes razón el precio de una única licencia es de 300 €, pero si lo que te interesa es distribuirla en una aplicación genérica puedes adquirir una licencia por 2000€ y podras firmar con todos los certificados que desees.

     
    jueves, 9 de julio de 2009 8:15
  • Ruben , esta claro que la tuya es una opción, igual no la más elegante, pero es una opción, el incoveniente por llamarlo de algun modo es que tienes que distribuir JVM (Java virtual machine) en el equipo cliente, y por mi experiencia cuanto más cosas instalas, mas cosas pueden fallar.
    jueves, 9 de julio de 2009 10:07
  • Hola Rubenmr,

    Podrias, por favor, publicar o mandarme el codigo para la validación contable de  la factura electrónica, y el codigo utilizado para firmar con mediate JAVA.

    Mi correo es: eferon13@hotmail.com
    Un saludo.

    viernes, 18 de septiembre de 2009 6:31
  • Buenos días:

    Tengo un fichero XML y quiero firmarlo. Algun ejemplo en Java, el fichero esta generado con XAdES

    Un saludom
    jueves, 5 de noviembre de 2009 8:43
  • Estoy empezando con el tema de la factura electronica, pero me he quedado estancado en el primer paso, poder generar un dataset tipificado con el esquema que nos proporciona AEAT, estoy usando la herramienta "XSD.exe" y el fallo es el siguiente :

    Utilidad de compatibilidad para esquemas Xml y DataTypes de Microsoft (R)
    [Microsoft (R) .NET Framework, Version 2.0.50727.42]
    Copyright (C) Microsoft Corporation. All rights reserved.
    Escribiendo el archivo 'C:\Archivos de programa\Microsoft Visual Studio 8\SDK\v2
    .0\Bin\facturaev3_2.vb'.
    Error: Error al procesar 'facturaev3_2.xsd'.
      - Error al generar código para el conjunto de datos ''.
      - No se puede convertir el contenido del archivo xml de entrada a un conjunto
    de datos. No se ha declarado el elemento 'http://www.w3.org/2000/09/xmldsig#:Sig
    nature'.
      - No se ha declarado el elemento 'http://www.w3.org/2000/09/xmldsig#:Signature
    '.

    Si desea más ayuda, escriba "xsd /?".

    No se como seguir, he buscado un monton y no encuentro nada.
    Gracias por vuestra atención.
    martes, 24 de noviembre de 2009 12:26
  • Hola,

    El problema, es que tb debes poner un segundo esquema ("xmldsig-core-schema.xsd"), ya que "Facturaev3_2.xsd" hace referencia a el.

    Para ello tienes que ejecutar el comando siguiente:

     

    “xsd Facturaev3_2.xsd xmldsig-core-schema.xsd ..."

     

    miércoles, 25 de noviembre de 2009 7:51
  • Fevimu, gracias por tu respuesta pero he probado lo que me comentas i me sigue fallando, podrias decirme el comando completo (¿tu lo has conseguido convertir?)
    martes, 1 de diciembre de 2009 10:27
  • No se si sera esto lo que te esta fallando...se me olvido comentarte que tienes que tener tambien el esquema "xmldsig-core-schema.xsd" en la misma caperta que el esquema "Facturaev3_2.xsd"

    El esquema "xmldsig-core-schema.xsd" puedes bajarlo de http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd

    Esta pagina http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx tambien te puede ayudar.


    Si me dices el comando que estas empleando, quizas te pueda ser de mas ayuda. El comando completo que yo emplee fue:

    xsd Facturaev3_2.xsd xmldsig-core-schema.xsd /c /n:FacturaElectronica

    martes, 1 de diciembre de 2009 16:37
  • Femivu muchas gracias  por tu ayuda, por fin he conseguido convertirlo a la clase vb.
    Me surgen nuevas dudas (estoy un poco verde con esto de los esquemas xsd), despues de rellenar todos los datos de la factura electronica, ¿como genero el xml?.
    miércoles, 2 de diciembre de 2009 14:36
  • Hola,

    Creo que deberias "formular una nueva pregunta" para tu consulta. Antendiento al titulo de este hilo del foro, no es un buen lugar para tu consulta.

    Estoy preparando la respuesta a tu consulta, y la contestare en el nuevo hilo que hagas.

    Además, si haces una nueva consulta conseguiras llamar la atención de otras personas del foro, ya que la gente no suele prestar mucha antención a hilos antiguos como este.

    Un saludo.
    jueves, 3 de diciembre de 2009 12:03
  • Ya tienes la nueva consulta realizada, te paso el enlace
    http://social.msdn.microsoft.com/Forums/es-ES/dotnetes/thread/5c3fefcc-3809-4050-8638-f3c8e65b850f
    jueves, 3 de diciembre de 2009 17:23
  • muy buenas! llevo unos dias liado con esto de la facturae y ya tengo el xml firmado, pero a la hora de validarlo me da errores en los tipos de datos que tienen un número fijo de decimales, la clase generada con xsd.exe no contiene los tipos de datos simples habilitados en el esquema para dicha representación.

    me preguntaba si alguno podría indicarme como resolver este problema, gracias
    viernes, 18 de diciembre de 2009 11:06
  • Perdona kiko,
    Si no te importa, me puedes comentar como has firmado el xml??
    Muchas gracias
    martes, 29 de diciembre de 2009 19:24
  • Perdona Rogrod,
    Has conseguido unas el xades.dll para firmar la factura en formato 3.2??

    Muchas gracias.
    martes, 29 de diciembre de 2009 19:29
  • Hola tengo muchos problemas para generar el xml de facturae desde .net. La verdad es que soy bastante novato y me han pedido que haga esto y la verdad no se casi por donde cogerlo. He intentado crear xsd y xml a partir de un dataset con el writexml pero no me valida el documento que genero. Nose quizá lo que estoy haciendo es una burrada.

    Si me podeis ayudar lo agradecería muchisimo, mi correo es: abarderas@nextcs.es

    Gracias.
    miércoles, 13 de enero de 2010 10:51
  • Hola Ruben, he leído que has conseguido hacer el código para generar el xml desde .net. Yo llevo varios días intentandolo y no consigo nada. Me baje los xsd desde la web y al hacer un readxml me da errores. Nose si por donde seguir. Si me puedes pasar el código que usas tú o darme algun nocion sobre como empezar lo agradecería muchísimo.

    Un Saludo, ni correo es abarderas@nextcs.es
    lunes, 18 de enero de 2010 9:09
  • Ahi os dejo un archivo que contiene una solución en VS2008 con un ejemplo de uso de mi libreria tanto para generación, como para recepción y validación OCSP.

    El enlace:->

    http://www.gtfacturae.es/Test.rar

    Espero que os sirva
    lunes, 18 de enero de 2010 14:21
  • Ahi os dejo un archivo que contiene una solución en VS2008 con un ejemplo de uso de mi libreria tanto para generación, como para recepción y validación OCSP.

    El enlace:->

    http://www.gtfacturae.es/Test.rar

    Espero que os sirva
    Da error al cargar el proyecto GTFacturae y no se puede ejecutar el ejemplo.
    martes, 19 de enero de 2010 7:55
  • Rubenmr,
    Bueno he modificado la solución para que no este incluido el proyecto gtfacturae.
    Tambien he añadido un pequeño video de ejemplo.

    enlaces:

    http://www.gtfacturae.es/Test.rar
    http://www.gtfacturae.es/factura-video.rar

    Un saludo.
    martes, 19 de enero de 2010 9:34
  • Vale perfecto, ahora si que lo ejecuta, firma y tal.

    He visto que las firma con el certificado incluido en la solucion (cert_demo.p12), mi pregunta es la siguiente.

    ¿Cómo se puede hacer para que capture los certificados instalados en Iexplorer, y poder seleccionar uno?

    Para poder firmar con mi certificado expedido por la FNMT o mediante el DNI electrónico (este último se guarda solo alli).

    Gracias por tu trabajo y tu ayuda.
    miércoles, 20 de enero de 2010 9:03
  • La libreria no incorpora de forma nativa la capacidad para cargar certificados instalados en navegadores.
    En el siguiente ejemplo de la msdn muetra como cargar certificados almacenados en contenedores de ese tipo.

    http://msdn.microsoft.com/es-es/library/ms180961%28VS.80%29.aspx

    En concreto esta función.

           //  Open the AddressBook (called Other in Internet Explorer)
            //  certificate store and search for a recipient
            //  certificate with which to encrypt the message. The certificate
            //  must have the subject name "Recipient1".
            static public X509Certificate2 GetRecipientCert()
            {
                //  Open the AddressBook local user X509 certificate store.
                X509Store storeAddressBook = new X509Store(StoreName.
                    AddressBook, StoreLocation.CurrentUser);
                storeAddressBook.Open(OpenFlags.ReadOnly);
    
                //  Display certificates to help troubleshoot the
                //  example's setup.
                Console.WriteLine(
                    "Found certs with the following subject names in the " +
                    "{0} store:",
                    storeAddressBook.Name);
                foreach (X509Certificate2 cert in storeAddressBook.Certificates)
                {
                    Console.WriteLine("\t{0}", cert.SubjectName.Name);
                }
    
                //  Get recipient certificate.
                //  For purposes of this sample, do not validate the
                //  certificate. Note that in a production environment,
                //  validating the certificate will probably be necessary.
                X509Certificate2Collection certColl = storeAddressBook.
                    Certificates.Find(X509FindType.FindBySubjectName,
                    recipientName, false);
                Console.WriteLine(
                    "Found {0} certificates in the {1} store with name {2}",
                    certColl.Count, storeAddressBook.Name, recipientName);
    
                //  Check to see if the certificate suggested by the example
                //  requirements is not present.
                if (certColl.Count == 0)
                {
                    Console.WriteLine(
                        "A suggested certificate to use for this example " +
                        "is not in the certificate store. Select " +
                        "an alternate certificate to use for " +
                        "signing the message.");
                }
    
                storeAddressBook.Close();
    
                return certColl[0];
            }

    El tipo retornado por la función(X509Certifcate2) , puede ser guardado a un archivo 'temporal' o no, y despues ser utilizado para realizar la firma. Algo asi como esto...
                //Cargamos el certificado firmante
    System.IO.FileStream fs = new FileStream(@"C:\cert.cert", FileMode.Create);
    X509Certificate2 certificado=GetRecipientCert();
    byte [] bytes=certificado.RawData;
    fs.Write(bytes,0,bytes.Length);
    fs.Flush();
    fs.Close();
    GTfacturaeClass.LoadCertificado((@"C:\cert.cert", passwordCertificado);
    Salu2.

    miércoles, 20 de enero de 2010 9:27
  • Tu herramienta es muy buena, pero como se puede firmar un xml ya generado con otra herramienta, he intentado hacer:

     

    Dim GTfacturaeClass As New GTFacturae.Facturae
    Dim fs As System.IO.FileStream = New FileStream("C:\cert.cert", FileMode.Create)
    Dim bytes() As Byte = cert.RawData

     

    fs.Write(bytes, 0, bytes.Length)
    fs.Flush()
    fs.Close()

     

    GTfacturaeClass.CargaFactura(DireccionXML)
    GTfacturaeClass.LoadCertificado("C:\cert.cert", "iupoy") ' passwordCertificado)
    GTfacturaeClass.Guardar(DireccionXML, True)

     

    GTfacturaeClass = Nothing

    Pero al hacer cargarfactura me pega un petardazo

    Muchas gracias por tu aportación

    miércoles, 20 de enero de 2010 10:41
  • Tambien he intentado


    Dim GTfacturaeClass As New GTFacturae.Facturae
    Dim fs As System.IO.FileStream = New FileStream("C:\cert.cert", FileMode.Create
    )
    Dim bytes() As Byte = cert.RawData

     

    fs.Write(bytes, 0, bytes.Length)
    fs.Flush
    ()
    fs.Close
    ()  

     

    GTfacturaeClass.LoadCertificado("C:\cert.cert", "iupoy") ' passwordCertificado)
    GTfacturaeClass.Firmar(DireccionXML)
     

     

    GTfacturaeClass = Nothing

    Pero al hacer GTfacturaeClass.Firmar(DireccionXML)  me casca.

    miércoles, 20 de enero de 2010 10:47
  • Diego, Por favor, pasame la factura que quieres cargar para ver donde esta cascando. Asi como el certificado firmante.
    miércoles, 20 de enero de 2010 15:33
  • La factura es:

    .......La he quitado porque no me he dado cuenta de los datos personales...............

    Esta factura esta validada correctamente en la herramienta de facturae
    Pero el certificado no te lo puedo pasar porque es el mio personal, como puedo crear otro para las pruebas y así podertelo pasar.

    Muchas gracias
    • Editado DiegoDGS jueves, 21 de enero de 2010 9:37 proteccion de datos
    miércoles, 20 de enero de 2010 16:19
  • Diego , subeme el archivo a algún sitio donde me lo pueda descargar.

    Este es el error que arroja al intentar cargar tu factura con mi libreria -->La etiqueta de apertura 'Province' en la línea 35 no coincide con la etiqueta de cierre de 'AddressInSpain'. Línea 37, posición 11.


    Este es el error que obtengo al intentar validar con la herramienta del ministerio. -> http://www11.mityc.es/FacturaE/

    FacturaE 3.0,cvc-elt.1: Cannot find the declaration of element 'm:Facturae'.
    FacturaE 3.1,: XML-20121: (Error Fatal) La etiqueta final no coincide con la etiqueta inicial 'Province'.
    FacturaE 3.2,cvc-elt.1: Cannot find the declaration of element 'm:Facturae'.

    miércoles, 20 de enero de 2010 17:27
  • Te dejo el xml en:

    Este es otro que ya he validadeo yo en http://www11.mityc.es/FacturaE/ y da OK


    http://www.galindosaeta.es/facturae/MR1743EFAC.xml




    Gracias
    jueves, 21 de enero de 2010 9:33
  • Hola de nuevo, he probado a leer los certificados de la biblioteca de IE y con esta funcion me los lee perfectamente y me devuelve el elegido:

    'Función para capturar el certificado
        Public Shared Function GetRecipientCert() As X509Certificate2
            Dim st As New X509Store(StoreName.My, StoreLocation.CurrentUser)
            st.Open(OpenFlags.[ReadOnly])
            Dim col As X509Certificate2Collection = st.Certificates
            Dim card As X509Certificate2 = Nothing
            Dim sel As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(col, "Certificados", "Selecciona uno para firmar", X509SelectionFlag.SingleSelection)
            If sel.Count > 0 Then
                Dim en As X509Certificate2Enumerator = sel.GetEnumerator()
                en.MoveNext()
                card = en.Current
            End If
            st.Close()
            Return card
        End Function

    Ahora la cuestión es poder firmar el XML con el certificado devuelto por esa función.

    He probado lo que dices Gabriel de guardar el certificado a un archivo para que luego lo cargue la DLL pero falla en:

    'Rescatamos la factura en XML
                    s_factura = facturae.ConseguirDatos(True, SchemaVersionType.Version31)

    "Referencia a objeto no establecida como instancia de un objeto."

    Gracias y aupa zaragoza jejeje
    jueves, 21 de enero de 2010 11:05
  • DiegoGs he vuelto a subir una nueva versión de la librería que corrige el problema, que venia dado por que el campo TotalFinancialExpenses lo consideraba como obligatorio y este no lo es, en tu fichero no viene dado, no comprobaba si era nulo y ahi estaba crujiendo, he subido una nueva versión que corrige el problema y carga tu factura correctamente.

    http://www.gtfacturae.es/Test.rar


    RubenMr si pudieras pasarme el proyecto
    donde te genera ese error o indicarme como reproducirlo, para poder identificar el bug y tratar de corregirlo.
    Por cierto, ¿eres mañico?

    Un saludo.
    viernes, 22 de enero de 2010 13:08
  • Gabriel, si soy mañico, del mismo zaragoza jejeje.

    mi email es:  ponte en contacto conmigo, hablamos y te mando lo q necesites.

    Un abrazo desde Zaragoza.
    viernes, 22 de enero de 2010 15:05

  • Me sigue dando este error:

    Message = "Referencia a objeto no establecida como instancia de un objeto."


    "   en System.Security.Cryptography.Xml.Xades.RSAKeyValue.GetXml(XmlDocument xmlDocument)
       en System.Security.Cryptography.Xml.Xades.KeyInfo.GetXml(XmlDocument xmlDocument)
       en System.Security.Cryptography.Xml.Xades.KeyInfo.GetXml()
       en System.Security.Cryptography.Xml.Xades.SignedXml.BuildDigestedReferences()
       en System.Security.Cryptography.Xml.Xades.SignedXml.ComputeSignature()
       en GTFacturae.Facturae.FirmaXADES(Stream stream)
       en GTFacturae.Facturae.ConseguirDatos(Boolean añadirfirma, SchemaVersionType version)
       en GTFacturae.Facturae.GuardarAVersion(String ruta, Boolean añadirfirma, SchemaVersionType version)
       en GTFacturae.Facturae.Guardar(String ruta, Boolean añadirfirma)
       en Amsystem.AMFacturaE.MGenericos.FirmarConGTFacturae(String DireccionXML, X509Certificate2 cert) en C:\AmNet\FACTURAE\FacturaE\FacturaE\AMFacturaE.vb:línea 313"


    He miradolo que rellena de la clase y veo que al hacer cargar factura, carga todos los datos de emisor de receptor, etc.. No rellena los campos de 

      TotalAEjecutar 0.0 Double
      TotalAPagar 0.0 Double
      TotalFactura 0.0 Double

    y a la hora de hacer el Guardar o a la hora de firmar da el petardazo. El certificado que estoy utilizando es el de la fábrica de moneda y timbre. Es el mio personal y parace que al hacer el loadcertificado no hace nada, porque no rellena la propiedad:

    -  Certificados {GTFacturae.X509Certificate2CollectionCOM} GTFacturae.IGTCollection
    +  GTFacturae.X509Certificate2CollectionCOM {GTFacturae.X509Certificate2CollectionCOM} GTFacturae.X509Certificate2CollectionCOM
      Count 0 Integer

    No se si la historia puede estar en que hay una unidad en negativo, que realmente es una entrega de producto en la misma factura.

    Un saludo y muchas gracias por lo que estás haciendo.


    lunes, 25 de enero de 2010 8:44
  • Creo que tienes un problema de versiones ya que a mi si que me lee tu factura correctamente.
    Asegurate que te descargaste la ultima versión que deje subida, que has referenciado ESA librería correctamente, esta reside en la carpeta Libs.
    Te dejo un video para que veas que SI que la lee.

     http://www.gtfacturae.es/prueba.rar


    Salu2.
    lunes, 25 de enero de 2010 14:25
  • Tengo la última version, si que me rellena tus propertys correctamente, lo único es que al firmar da el petardazo. Voy a echar un vistazo a ver si puedo dar con la tecla.  He visto qui con el certificado que tu tienes

    cert_demo.p12"

     

    , "1111"

    si que lo carga, pero sin embargo con un certificado de la fabrica de moneda y timbre no.

    Muxo por saco estoy dando ya, jejejeje.
    lunes, 25 de enero de 2010 15:58
  • DiegoGS, create un proyecto de consola, añade la referencia a la libreria, copia el certificado de moneda y timbre tambien  el que suministro yo en el ejemplo 'cert_demo.p12' . Cambia la propiedad 'Copy to Output Directory'  a la opcion  'Copy Always' . Ejecuta y dime el resultado para ambos certificados.

    Sustituye las rutas de archivo por las que tu utilices.


    using System;
    using GTFacturae;

    namespace ConsoleApplication1
    {
    class Program

    {

    private static string Ruta
    {
    get
    {
    return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    }
    }

    static void Main(string[] args)
    {
    GTFacturae.Facturae file = new GTFacturae.Facturae();
    file.LoadCertificado(Ruta + "\\cert_demo.p12", "1111");
    file.Firmar(@"D:\MR1743EFAC.xml");
    file = null;
    }
    }
    }

    Un apunte.

    Si con tu certificado falla, prueba a cargarlo del siguiente modo.

    Añade la referencia a la libreria System.Security.

    Utiliza la siguiente sentencia.
    Si la variable cert contiene los datos de tu certificado, a simple vista no veo que puede estar ocurriendo.

    System.Security.Cryptography.X509Certificates.X509Certificate2 cert=new System.Security.Cryptography.X509Certificates.X509Certificate2(file,password)

    Me indicas el resultado.

    Un salduo.
    lunes, 25 de enero de 2010 16:59
  • Me ha funcionado exportando el certificado a un archivo, pero desde la heramienta de certificados del explorer, al crear yo el archivo no funciona.
    martes, 26 de enero de 2010 8:16
  • Me ha funcionado exportando el certificado a un archivo, pero desde la heramienta de certificados del explorer, al crear yo el archivo no funciona.
    A mi me pasa lo mismo, con la funcion q puse mas arriba, se consigue mostrar la lista de certificados del IE pero a la hora de guardarlos en un archivo .cert o .p12 con la sentencia que detalla Gabriel, da error al firmar el XML.

    La solución podría ser arreglar eso o q Gabriel modificara la DLL para que se pudiera firmar directamente con el certificado que te devuelve la funcion GetRecipientCert().

    A ver si entre todos conseguimos algo, jeje.

    Saludos
    martes, 26 de enero de 2010 8:29
  • Ya he hencontrado la solución:

     

    Dim fs As System.IO.FileStream = New FileStream("C:\kk\cert.p12", FileMode.Create)
    Dim bytes() As Byte = cert.Export(X509ContentType.Pkcs12, "1111")
    fs.Write(bytes, 0, bytes.Length)
    fs.Flush()
    fs.Close()

     

    GTfacturaeClass.LoadCertificado("C:\kk\cert.p12", "1111")
    GTfacturaeClass.Firmar(DireccionXML)

    La historia está en que al hacer Dim bytes() As Byte = cert.RawData , el certificado va sin formato, sin embargo al hacer el export el  Archivo va con formato de certificado.


    Funciona correctamente.
    Muchas gracias, algún dia tendrás que decir como has conseguido firmar, que me tienes en ascuas. Porque yo he conseguido casi firmar igual pero me faltaba lo del tema de la firma de tiempo xades.

    martes, 26 de enero de 2010 8:36
  • Me apunto lo de 'Dim bytes () As Byte = cert . Export ( X509ContentType . Pkcs12 , "1111" )'

    Me alegro que os funcione :).


    martes, 26 de enero de 2010 9:41
  • Creo que tienes un problema de versiones ya que a mi si que me lee tu factura correctamente.
    Asegurate que te descargaste la ultima versión que deje subida, que has referenciado ESA librería correctamente, esta reside en la carpeta Libs.
    Te dejo un video para que veas que SI que la lee.

     http://www.gtfacturae.es/prueba.rar


    Salu2.

    Buenas... estaria interesado en echarle un vistazo a tu libreria, bueno más bien a utilizarla, ya que quiero empezar a firmar las facturas... ¿de donde puedo descargarla?... el enlace que has puesto no funciona.

    O alguien que la tenga y la pueda poner para descargar.

    Gracias y buen trabajo.
    jueves, 18 de febrero de 2010 19:13
  • No se si sera esto lo que te esta fallando...se me olvido comentarte que tienes que tener tambien el esquema "xmldsig-core-schema.xsd" en la misma caperta que el esquema "Facturaev3_2.xsd"

    El esquema "xmldsig-core-schema.xsd" puedes bajarlo de http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd

    Esta pagina http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx tambien te puede ayudar.


    Si me dices el comando que estas empleando, quizas te pueda ser de mas ayuda. El comando completo que yo emplee fue:

    xsd Facturaev3_2.xsd xmldsig-core-schema.xsd /c /n:FacturaElectronica


    GRACIAS!!! Estaba ya desesperado por crear la clase y al final opté por quitarle la parte de la firma en el esquema de la factura (yo no voy a firmarlo por lo que no me hacía falta).

     

    jueves, 22 de abril de 2010 15:49
  • Hola Gabriel,

    Muchas gracias por tu esfuerzo. Estoy intentando acceder al link en donde has dejado el ejemplo, pero no me funcioa.

    ¿podrías enviarmelo por mail?

    Gracias.

    lunes, 26 de abril de 2010 9:20
  • Hola:

    Asumiendo que ya teneis las clases de eFactura generadas a partir del XSD (en mi caso la version 3.2) pueden firmar el XML resultante utilizando este código

    Este codigo sirve para firmar cualquier XML. Lo unico extra que teneis que hacer para incluirlo en vuestras soluciones es resolver el mecanismo de seleccion del certificado que se utiliza para firmar.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Diagnostics;
    using System.Xml;
    using System.Security.Cryptography.Xml;
    
    namespace eFacturaTest
    {
      /// <summary>
      /// Clase para gestionar las firmas digitales de un archivo en formato XML. 
      /// </summary>
      class FirmadorXml
      {
        /// <summary>
        /// Indica si el certificado ya ha sido solicitado al usuario.
        /// </summary>
        private static bool miCertificadoSolicitado;
        /// <summary>
        /// Certificado que se utiliza para firmar digitalmente, si es null despues de haberlo
        /// solicitado al usuario se utiliza una llave creada en el almacen de claves de Windows.
        /// </summary>
        private static X509Certificate2 miCertificado;
    
        /// <summary>
        /// Constructor.
        /// </summary>
        public FirmadorXml()
        {
        }
    
        /// <summary>
        /// Firma un documento XML si se selecciona un certificado.
        /// </summary>
        /// <param name="xmlDoc"></param>
        public void Firmar(XmlDocument xmlDoc)
        {
          GarantizarCertificadoDeUsuario();
    
          if (miCertificado == null)
          {
            //si no se ha seleccionado un certificado para firmar, no se firma el documento XML
            return;
          }
    
          AsymmetricAlgorithm key = miCertificado.PrivateKey;
    
          SignedXml signedXml = new SignedXml(xmlDoc);
          signedXml.SigningKey = key;
    
          // Create a reference to be signed.
          Reference reference = new Reference();
          reference.Uri = "";
    
          XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
          reference.AddTransform(env);
    
          signedXml.AddReference(reference);
    
          signedXml.ComputeSignature();
    
          XmlElement xmlDigitalSignature = signedXml.GetXml();
    
          xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        }
    
        /// <summary>
        /// Verifica la firma digital de un documento XML.
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <returns></returns>
        public bool VerificarFirma(XmlDocument xmlDoc)
        {
          XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
          if (nodeList.Count == 0)
          {
            //el documento no está firmado, se considera valido
            return true;
          }
          else
          {
            //si tiene una firma debe ser de un certificado
            return VerificarFirmaConCertificado(xmlDoc);
          }
        }
    
        /// <summary>
        /// Verifica la firma digital de un documento XML utilizando un certificado de usuario.
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <returns></returns>
        private bool VerificarFirmaConCertificado(XmlDocument xmlDoc)
        {
          X509Certificate2 certificado = SeleccionarCertificado();
    
          if (certificado != null)
          {
            XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
    
            SignedXml signedXml = new SignedXml(xmlDoc);
            signedXml.LoadXml((XmlElement)nodeList[0]);
    
            return signedXml.CheckSignature(certificado, true);
          }
          else
          {
            return false;
          }
        }
    
        /// <summary>
        /// Solicita el certificado al usuario una sola vez por sesión.
        /// </summary>
        public static void GarantizarCertificadoDeUsuario()
        {
          if (!miCertificadoSolicitado)
          {
            miCertificado = SeleccionarCertificado();
            miCertificadoSolicitado = true;
          }
        }
    
        /// <summary>
        /// Selecciona un certificado de usuario.
        /// </summary>
        /// <returns></returns>
        public static X509Certificate2 SeleccionarCertificado()
        {
          //TODO: Sustituirse por una invocacion a una interfaz que se le inyecta a esta clase para 
          //seleccionar certificados.
    
          //Cargar certificados del usuario que contienen llave privada
          X509Store store = new X509Store(StoreLocation.CurrentUser);
          store.Open(OpenFlags.ReadOnly);
          try
          {
            X509Certificate2 certSeleccionado = null;
    
            foreach (X509Certificate2 cert in store.Certificates)
            {
              if (cert.HasPrivateKey)
              {
                if (certSeleccionado == null)
                {
                  //tomaremos el primero de ellos para este ejemplo
                  certSeleccionado = cert;
                }
    
                Debug.WriteLine(String.Format("Certificado entontrado. Subject: {0}, Issuer: {1}, Expiration: {2}, FriendlyName: {3}",
                  cert.SubjectName.Name, cert.IssuerName.Name, cert.GetExpirationDateString(), cert.FriendlyName));
              }
            }
    
            return certSeleccionado;
          }
          finally
          {
            store.Close();
          }
        }
      }
    }
    

     

    Se puede probar con este otro código:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using EFactura;
    using System.IO;
    using System.Diagnostics;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace eFacturaTest
    {
      class Program
      {
        static void Main(string[] args)
        {
          Facturae efact = new Facturae();
    
          efact.Invoices = new InvoiceType[] 
          { 
            new InvoiceType()
            {
              InvoiceHeader = new InvoiceHeaderType()
              {
                InvoiceNumber = "1234",
                InvoiceSeriesCode = "01"
              }
            }
          };
    
          XmlDocument xmld = Serializar(efact);
    
          FirmadorXml firmadorXml = new FirmadorXml();
    
          firmadorXml.Firmar(xmld);
    
          //comprobar que el archivo se ha firmado correctamente deserializando
          Facturae efactFirmado = Deserializar(xmld);
        }
    
        private static XmlDocument Serializar(Facturae efact)
        {
          using (MemoryStream ms = new MemoryStream())
          {
            using (XmlTextWriter xmltw = new XmlTextWriter(ms, Encoding.UTF8))
            {
              XmlSerializer xmlser = new XmlSerializer(typeof(Facturae));
              xmlser.Serialize(xmltw, efact);
    
              ms.Seek(0, SeekOrigin.Begin);
              XmlDocument xmld = new XmlDocument();
              xmld.Load(ms);
              return xmld;
            }
          }
        }
    
        private static Facturae Deserializar(XmlDocument xmld)
        {
          using (XmlTextReader xmltr = new XmlTextReader(xmld.OuterXml, XmlNodeType.Document, null))
          {
            XmlSerializer xmlser = new XmlSerializer(typeof(Facturae));
            return xmlser.Deserialize(xmltr) as Facturae;
          }
        }
      }
    }
    

    Espero que os sirva

    Saludos

    jueves, 13 de mayo de 2010 16:57
  • DiegoGs he vuelto a subir una nueva versión de la librería que corrige el problema, que venia dado por que el campo TotalFinancialExpenses lo consideraba como obligatorio y este no lo es, en tu fichero no viene dado, no comprobaba si era nulo y ahi estaba crujiendo, he subido una nueva versión que corrige el problema y carga tu factura correctamente.

    http://www.gtfacturae.es/Test.rar


    RubenMr si pudieras pasarme el proyecto
    donde te genera ese error o indicarme como reproducirlo, para poder identificar el bug y tratar de corregirlo.
    Por cierto, ¿eres mañico?

    Un saludo.

    Hola buenas.

    Estoy intentando firmar electronicamente facturas y hasta ahora he conseguido firmar  verificar xml ya hechos. El problema es que me estoy liando un poco con la generación del archivo xml. No se si teneis algun ejemplo de como hacerlo, o si me podeis echar una mano, o sino, en ultimo caso, igual alguien me lo puede pasar . Empiezo a estar ya desesoerado,

    Gracias, un saludo.

    miércoles, 2 de junio de 2010 14:40
  • Buenos días

    Yo estoy un poco igual que ilopez.

    Tengo que crear el fichero facturae XML desde Visual Basic 2005 y no he trabajado nunca con estos ficheros y no se por donde empezar

    Agradeceria MUCHISIMO si alguien que ya lo haya desarrollado me pudiera pasar el codigo o algun ejemplo para poder hacerlo.Solo necesito la generacion del XML

    .La firma ya la harian manualmente

    Llevo días perdidos intentando sacar algo en claro y no me aclaro

    .Desde ya Muchas gracias a cualquiera que pueda ayudarme  ( mi mail es albertetsbd@hotmail.com)

    Un saludo

     


    Albert
    jueves, 3 de junio de 2010 7:22
  • Siguiendo el foro desde arriba hay una reseña a la creación de los xml:

    No se si sera esto lo que te esta fallando...se me olvido comentarte que tienes que tener tambien el esquema "xmldsig-core-schema.xsd" en la misma caperta que el esquema "Facturaev3_2.xsd"

    El esquema "xmldsig-core-schema.xsd" puedes bajarlo de http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd

    Esta pagina http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx tambien te puede ayudar.


    Si me dices el comando que estas empleando, quizas te pueda ser de mas ayuda. El comando completo que yo emplee fue:

    xsd Facturaev3_2.xsd xmldsig-core-schema.xsd /c /n:FacturaElectronica

    Lo único que tienes que hacer es crear la clase a partir del XSD, rellenar todas sus propiedades que te hagan falta y serializarla, esto crea un xml.

    jueves, 3 de junio de 2010 11:08
  • Gracias por la respuesta DiegoDGS. Voy a ver como me las apaño por ahí

     

    Un saludo.

    jueves, 10 de junio de 2010 23:29
  • Hola.

    Estoy intentando crear una aplicacion para generar la factura en formato facturae, ¿Podrias enviarme algo de codigo para comenzar?. Me estoy volviendo loco y no encuentro nada para vb.net.

    Gracias

    Un saludo

    miércoles, 12 de diciembre de 2012 7:40
  • Estimado Ruben,

    Me puedes ayudar con la informacion en Java para firmar los XML, enviando a mi correo cesaraugustoespinoza@hotmail.com

    Muchas gracias

    viernes, 18 de julio de 2014 22:35
  • me pueden ayudar con el codigo de la firma del xml en vb.net

    a este correo barcericky18@hotmail.com
    martes, 23 de septiembre de 2014 21:33
  • Hola, perdon.

    Pero a fecha de hoy a un te sige funcionando?, tengo problema que no logro incrustar la firma siempre me devuelve "Firma inválida. No se pudo obtener el certificado firmante " huvo alguna modificacion o algo

    te lo agradeceria toda informacion extra que me puedas proporcionar

    miércoles, 5 de noviembre de 2014 17:40
  • Estuve revisando la respuesta que da algorithmer, es correcta pero en ese caso me está firmando con el formato XDsig que es la base de XAdes, para firmar con este formato hay un proyecto XAdES .Net en esta url https://xadesnet.codeplex.com

    pero sigue firmando con el mismo estandar XDsig, faltan las etiquetas "ds" en la "signature"-

    Pero existe otro proyecto de Microsoft France el Microsoft.XAdes, http://www.microsoft.com/france/interop/ressources/xades.aspx, pero al firmar tengo ciertos problemas, si le pueden revisar este último proyecto, tiene un problema al adquirir el certificado, nunca funciona a la primera, si pueden revisar este proyecto y dar la solución para que funcione sin ningún problema sería lo ideal. 

    También hay el SecureBlackBox de Eldos, funciona perfectamente para firmar XAdes con el pero de que es pagada.

    Estoy haciendo lo mismo que facturae pero en Ecuador, alguien una mano que no soy tan experto en .net.

    • Editado JavierJiron viernes, 14 de noviembre de 2014 1:38
    • Propuesto como respuesta JavierJiron viernes, 14 de noviembre de 2014 1:39
    viernes, 14 de noviembre de 2014 1:33
  • Aquí les dejo el código funcionando, espero respuestas y comentarios para mejorar ese código.

    /* FirmaXML 2.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. PD. Comentario del autor original.
    
       Ensamblaje .NET para firma XMLDSig y XAdES BES, utilizando el ensamblaje Microsoft.Xades,
       OpenSource de Microsoft France.
    
       Esta versión de FirmaXML genera un DLL ActiveX COM+ para ser utilizado en otros lenguajes
       de programación como Delphi, Lazarus, VB6, Visual FoxPro, etc. */
    
    using System;
    using System.IO;
    using System.Xml;
    using System.Runtime.InteropServices;
    using System.EnterpriseServices;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml;
    using Microsoft.Xades;
    
    namespace JironAsociados.FirmaXML
    {
    
        public interface IFirmaXML
        {
            string FirmarXDsig(string XMLFILE, string NSERIE);
            string FirmarXAdes(string XMLFILE, string NSERIE);
        }
    
        /* Permitimos que esta clase pueda ser exportada como interfaz COM, para ser utilizada en 
           entornos no .NET también. */
        [Synchronization(SynchronizationOption.Required), 
        JustInTimeActivation(true), 
        ObjectPooling(Enabled=true)]    
        public class FirmaXML : ServicedComponent , IFirmaXML
        {
    
            public FirmaXML() { }
    
            [AutoComplete(true)]
            public string FirmarXDsig(string XMLFILE, string NSERIE)
            {
                /* Método que recibe el texto de un documento XML y regresa ese mismo texto pero conteniendo 
                   una firma digital XMLDSig envolvente.
           
                   Parámetro XMLFILE: Ubicación del documento a firmar.
                   Parámetro NSERIE: Número de Serie del certificado a utilizar. */
    
                // Obtenemos el certificado correspondiente al Número de serie dado
                X509Certificate2 Certificado = BuscarCertificado(NSERIE);
    			// Para utilizar un archivo pkcs de firmado digital
                //X509Certificate2 Certificado = new X509Certificate2("<Ubicación del archivo pkcs>", "<contraseña>");
    
                // 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.Load(XMLFILE);
                //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;
            }
    
            [AutoComplete(true)]
            public string FirmarXAdes(string XMLFILE,string NSERIE)
            {
    			/* Método que recibe el texto de un documento XML y regresa ese mismo texto pero conteniendo 
                   una firma digital XAdES BES envolvente.
           
                   Parámetro XMLFILE: Ubicación del documento a firmar.
                   Parámetro NSERIE: Número de Serie del certificado a utilizar. */
    
                string resultado;
    
    			// Obtenemos el certificado correspondiente al Número de serie dado
    			X509Certificate2 Certificado = BuscarCertificado(NSERIE);
    			// Para utilizar un archivo pkcs de firmado digital
    			//X509Certificate2 Certificado = new X509Certificate2("<Ubicación del archivo pkcs>", "<contraseña>");
    
    			// Procedimiento para firmar con el objeto XadesSignedXml de Microsoft.Xades para firmar XML
    			// con firma envolvente
    			XmlDocument Documento = new XmlDocument();
                Documento.Load(XMLFILE);
    
                XadesSignedXml Firma = new XadesSignedXml(Documento);
                RSACryptoServiceProvider Llave = Certificado.PrivateKey as RSACryptoServiceProvider;
                Firma.SigningKey = Llave;
    
    			// Agregamos referencias y objetos necesarios para la firma
                Reference Referencia = new Reference();
                Referencia.Uri = "";  // Tomar ("digerir") todo el documento al crear la firma
                Referencia.AddTransform(new XmlDsigEnvelopedSignatureTransform());
                Firma.AddReference(Referencia);
                XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform();
                Referencia.AddTransform(xmlDsigC14NTransform);
                XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform();
                Referencia.AddTransform(xmlDsigEnvelopedSignatureTransform);     
    
    			/* 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
    
                try
                {
                    Firma.ComputeSignature();
                    Documento.DocumentElement.AppendChild(Documento.ImportNode(Firma.GetXml(), true));
                    resultado = Documento.OuterXml;
                }
                catch (Exception exception)
                {
                    resultado = "Problema en la firma: " + exception.Message;
                }
    
    
                // Devolvemos el XML firmado o el error*/
                return resultado;
            }
    
            protected static X509Certificate2 BuscarCertificado(string NSERIE)
            {
                // Método para obtener el certificado que pertenece a un Número de Serie
    
                // 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)
                    if (Resultado.GetSerialNumberString() == NSERIE)
                        return Resultado;
    
                throw new Exception("No hay un certificado instalado para el Número de serie que se indicó.");
            }
        }
    }

    • Propuesto como respuesta JavierJiron viernes, 14 de noviembre de 2014 12:28
    viernes, 14 de noviembre de 2014 12:28
  • Perfectisimo! muchisimas gracias :)


    lunes, 24 de noviembre de 2014 10:15
  • Me alegro que este hilo siga vivo, pues he retomado otra vez el tema de la firma. Viendo tu código lo he implementado y efectivamente firma, pero no me valida la firma la pagina de validación de www.facturae.es.

    ¿Ignoro la validación o es porque no es correcta la firma?.

    miércoles, 3 de diciembre de 2014 15:36
  • Hola Shargon.

    Como resolviste lo de microsoft.xades?

    lunes, 8 de diciembre de 2014 12:48
  • Hola Shargon.

    Como resolviste lo de microsoft.xades?

    Tienes que descargar la solución  y compilarla. Luego añades la referencia y funcionando.
    jueves, 11 de diciembre de 2014 11:07
  • Aquí les dejo el código funcionando, espero respuestas y comentarios para mejorar ese código.

    /* FirmaXML 2.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. PD. Comentario del autor original.
    
       Ensamblaje .NET para firma XMLDSig y XAdES BES, utilizando el ensamblaje Microsoft.Xades,
       OpenSource de Microsoft France.
    
       Esta versión de FirmaXML genera un DLL ActiveX COM+ para ser utilizado en otros lenguajes
       de programación como Delphi, Lazarus, VB6, Visual FoxPro, etc. */
    
    using System;
    using System.IO;
    using System.Xml;
    using System.Runtime.InteropServices;
    using System.EnterpriseServices;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml;
    using Microsoft.Xades;
    
    namespace JironAsociados.FirmaXML
    {
    
        public interface IFirmaXML
        {
            string FirmarXDsig(string XMLFILE, string NSERIE);
            string FirmarXAdes(string XMLFILE, string NSERIE);
        }
    
        /* Permitimos que esta clase pueda ser exportada como interfaz COM, para ser utilizada en 
           entornos no .NET también. */
        [Synchronization(SynchronizationOption.Required), 
        JustInTimeActivation(true), 
        ObjectPooling(Enabled=true)]    
        public class FirmaXML : ServicedComponent , IFirmaXML
        {
    
            public FirmaXML() { }
    
            [AutoComplete(true)]
            public string FirmarXDsig(string XMLFILE, string NSERIE)
            {
                /* Método que recibe el texto de un documento XML y regresa ese mismo texto pero conteniendo 
                   una firma digital XMLDSig envolvente.
           
                   Parámetro XMLFILE: Ubicación del documento a firmar.
                   Parámetro NSERIE: Número de Serie del certificado a utilizar. */
    
                // Obtenemos el certificado correspondiente al Número de serie dado
                X509Certificate2 Certificado = BuscarCertificado(NSERIE);
    			// Para utilizar un archivo pkcs de firmado digital
                //X509Certificate2 Certificado = new X509Certificate2("<Ubicación del archivo pkcs>", "<contraseña>");
    
                // 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.Load(XMLFILE);
                //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;
            }
    
            [AutoComplete(true)]
            public string FirmarXAdes(string XMLFILE,string NSERIE)
            {
    			/* Método que recibe el texto de un documento XML y regresa ese mismo texto pero conteniendo 
                   una firma digital XAdES BES envolvente.
           
                   Parámetro XMLFILE: Ubicación del documento a firmar.
                   Parámetro NSERIE: Número de Serie del certificado a utilizar. */
    
                string resultado;
    
    			// Obtenemos el certificado correspondiente al Número de serie dado
    			X509Certificate2 Certificado = BuscarCertificado(NSERIE);
    			// Para utilizar un archivo pkcs de firmado digital
    			//X509Certificate2 Certificado = new X509Certificate2("<Ubicación del archivo pkcs>", "<contraseña>");
    
    			// Procedimiento para firmar con el objeto XadesSignedXml de Microsoft.Xades para firmar XML
    			// con firma envolvente
    			XmlDocument Documento = new XmlDocument();
                Documento.Load(XMLFILE);
    
                XadesSignedXml Firma = new XadesSignedXml(Documento);
                RSACryptoServiceProvider Llave = Certificado.PrivateKey as RSACryptoServiceProvider;
                Firma.SigningKey = Llave;
    
    			// Agregamos referencias y objetos necesarios para la firma
                Reference Referencia = new Reference();
                Referencia.Uri = "";  // Tomar ("digerir") todo el documento al crear la firma
                Referencia.AddTransform(new XmlDsigEnvelopedSignatureTransform());
                Firma.AddReference(Referencia);
                XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform();
                Referencia.AddTransform(xmlDsigC14NTransform);
                XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform();
                Referencia.AddTransform(xmlDsigEnvelopedSignatureTransform);     
    
    			/* 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
    
                try
                {
                    Firma.ComputeSignature();
                    Documento.DocumentElement.AppendChild(Documento.ImportNode(Firma.GetXml(), true));
                    resultado = Documento.OuterXml;
                }
                catch (Exception exception)
                {
                    resultado = "Problema en la firma: " + exception.Message;
                }
    
    
                // Devolvemos el XML firmado o el error*/
                return resultado;
            }
    
            protected static X509Certificate2 BuscarCertificado(string NSERIE)
            {
                // Método para obtener el certificado que pertenece a un Número de Serie
    
                // 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)
                    if (Resultado.GetSerialNumberString() == NSERIE)
                        return Resultado;
    
                throw new Exception("No hay un certificado instalado para el Número de serie que se indicó.");
            }
        }
    }

    Por lo que veo Microsoft.Xades usa el schema 1.1.1 de Xades y no la 1.2.2 requerida por FacturaE. Alguien tiene este problema actualmente=
    jueves, 11 de diciembre de 2014 12:56
  • A mi me pasa lo mismo, no me valida la firma en la dirección:

    http://sedeaplicaciones2.minetur.gob.es/FacturaE/ValidarCompleto

    Viendo la estructura con otras válidas no son igual.

    ¿Alguna solución?

    martes, 16 de diciembre de 2014 12:55
  • en este blog tienen posteada una solución para firma las facturas, y parece ser que sí funciona y valida: http://sviudes.blogspot.com.es/2010/05/facturae-con-net-y-c.html


    Saludos / Regards

    lunes, 22 de diciembre de 2014 15:46
  • Hola. Imagino que ya será conocido, pero por si acaso les dejo un enlace a la libreria facilitada por las Administraciones Públicas para la firma XAdes. Esta basada en la libreria francesa .NET de Microsoft.

    https://administracionelectronica.gob.es/ctt/firmaxadesnet

    Un saludo

       Rubén

    viernes, 27 de enero de 2017 14:21

  • Instead, use a cached local copy in the same directory as your XSD,

    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
               schemaLocation="xmldsig-core-schema.xsd"/>

    or use an absolute path a:

    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"   
               schemaLocation="file:///D:/xmldsig-core-schema.xsd" />

    viernes, 25 de enero de 2019 15:21