EldoS | Feel safer!

Software components for data protection, secure storage and transfer

factura-e webservice (enviar factura electrónica a face en España)

Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.
#35079
Posted: 11/23/2015 08:02:26
by Luis Concepcion (Standard support level)
Joined: 07/21/2007
Posts: 9

SPANISH
-------
Hola.

Llevo tiempo intentando enviar las facturas vía webservice al servidor de face, pero siempre obtengo el error "La firma de la petición SOAP no es válida".

1. La factura electrónica es válida. Puedo validarla e incluso enviarla usando la web de entrada de facturas de face:
https://face.gob.es/#/es/facturas/validar-visualizar-facturas

Lo mismo ocurre si en vez de enviar una factura, lo que hago es consultar estados, Administraciones, etc.

2. El problema está con la petición soap para usar el webservice. Concretamente con la firma de la petición.
Tal como ellos indican en la documentación, todas las peticiones soap deben estar firmadas. Bien. ¿Cómo?

3. Para simplificar el ejemplo, en vez de enviar una factura, lo hago con la opción para obtener la lista de Administraciones (consultarAdministraciones)

La firma a usar debe ser OASIS WSSecurity 1.0 X509 Token Profile, con el bloque header, etc.

He probado mil maneras diferentes de firmar la petición soap, XAdES-BES, sin sin XAdES, etc. pero no hay manera.

¿Alguien ha conseguido enviar una petición soap al webservice de face y obtener una respuesta?



ENGLISH
-------
Hi!

I'm trying to use the face webservice to send electronic invoices directly, but I'm getting 'soap request signature is not valid' every time.

1. The electronic invoice is valid. I can verify and send it to the face using the official web page they provide to send invoices:
https://face.gob.es/#/es/facturas/validar-visualizar-facturas

2. The problem is with the soap request to send the invoice using their oficial webservice. Specifically with the SOAP signature.
As they explain: "All soap request have to be signed". Ok. HOW

3. To simplify the example, I will use the simplest request supported: retrieve list of available Organizations (consultarAdministraciones)

As they say, all soap request have to be signed using OASIS WSSecurity 1.0 X509 Token Profile. Inside the header block, it must be included a 'security' block with all necessary data to validate the signature.

SIGNED SOAP REQUEST
-------------------

<?xml version="1.0" encoding="UTF-8"?>



<soapenv:Header>
<wsse:Security
soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<wsse:BinarySecurityToken
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-5A5C126069B253F2B0135998798458616"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">............</wsse:>

<ds:Signature
Id="Signature-11"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>

<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-12">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>.............</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
.........
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-5A5C126069B253F2B0135998798458717">
<wsse:SecurityTokenReference
wsu:Id="STRId-5A5C126069B253F2B0135998798458718"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Reference URI="#CertId-5A5C126069B253F2B0135998798458616"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp
wsu:Id="Timestamp-10"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2013-02-04T14:26:24.586Z</wsu:Created>
<wsu:Expires>2013-02-04T14:31:24.586Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>



<!-- BODY -->


</soapenv:Envelope>
#35082
Posted: 11/23/2015 09:42:19
by Ken Ivanov (EldoS Corp.)

Hi Luis,

Thank you for getting in touch with us.

Did you try signing the request as shown in the SecureSOAP sample (which is included in default SecureBlackbox installation; please check the XMLBlackbox directory in the samples folder)? SOAP signatures are different and sort of orthogonal to XAdES, and the governmental service might only accept one of the signature types.

If you did but with to no avail, is there any chance that you can get a sample signed request for us (maybe on Spanish governmental web site), OR, maybe a sample response (as it might be signed with the same method)? Having a working example it would be much easier to understand what kind of requests they expect and what can be done about it.

Ken
#35089
Posted: 11/23/2015 11:44:44
by Luis Concepcion (Standard support level)
Joined: 07/21/2007
Posts: 9

Hi, Ken.

Yes, I'm using the SecureSOAP sample Project to add the signature headers block to the soap request. I have tried 'WSS Signature Handler' + 'Sign Body' option.

Then in Embed Certificate Option I tried all of them, and enable/disable XAdES options.

The only soap request sample available is the one posted in the previous post.
And this is its signed response:

Code
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-wssecurity-utility-1.0.xsd">
<SOAP-ENV:Header xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/
secext">
<wsse:Security>
<wsse:BinarySecurityToken
EncodingType="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-1363779078359.7">MIGf...qB5Q+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:SignatureMethod Algorithm="http://www.w3.org/TR/
2001/REC-xml-c14n-20010315#WithComments"/>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:Reference URI="#id-1363779078359.7">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/
TR/2001/REC-xml-c14n-20010315"/>
</ds:Transforms>
<ds:DigestedMethod Algorithm="http://www.w3.org/
2000/09/xmldsig#sha1"/>
<ds:DigestedValue>eQhMOl9VLm+QJxT/rRyb/
a0FnBQ=</ds:DigestedValue>
</ds:Reference>
<ds:SignatureValue>v9rfyqtFdbfiq6Usiw5illtvZpUYkBP6hg795YPKzJwoKqgKe6w9X+FIMb2CMl5WD0Xzt6igJlIAVkr4PP4eWBN6fmZGg8ejaXGzUTQwf/
iElUjgnFrmscq/8Wu/8L4nE4PaXq7XocwPJUJ44/rWr7C241jJSG/
UNPBcn61peSk=</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference
EncodingType="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-x509-token-profile-1.0#X509v3"
URI="#CertId-1363779078359.7"/>
</ds:KeyInfo>
</ds:SignedInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:id="id-1363779078359.7">
<!-- BODY -->
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
#35095
Posted: 11/24/2015 06:25:00
by control tecnia (Standard support level)
Joined: 03/29/2010
Posts: 5

Hola Luis:
Yo tambien sufri un monton con esto. Te comento como lo solucioné. Tienes que instalar WSE settings 3.0 en el proyecto. Luego haces clic con el boton derecho en la solucion en Wse settings 3.0 pones la configuración que te indico los pantallazos adjuntos.

El codigo para enviar la factura es:

<English>
Hello:
I can send invoce using the following code, but first I configure the solution (c# 2010) with the Wse settings that I attach in the picture.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security.X509;
using Microsoft.Web.Services3.Design;
using System.Security.Cryptography;

….
//El servicio web https://webservice.face.gob.es/facturasspp2?wsdl
//aparece aquí como ProduccionOctubre2015

public class resultadoEnvio
{
public bool ok = false;
public string referenciaOk = "";
public string resultadoError = "";
}

….

//Los parámetros son:
// El certificado a utilizar
// el nombre del fichero .xsig a enviar al face
// y la dirección de email a la que el face remitirá las notificaciones de como va procesando la factura utilizar
//
// El resultado es del tipo resultadoEnvio
public static resultadoEnvio mandarUnaFra(
System.Security.Cryptography.X509Certificates.X509Certificate2 cert
string nombrefichero,string email)
{
resultadoEnvio resultado = new resultadoEnvio();
resultado.ok = false;
ProduccionOctubre2015.FacturaSSPPWebServiceProxyServiceWse proxyProduccionOctubre2015 =
new ProduccionOctubre2015.FacturaSSPPWebServiceProxyServiceWse();
proxyProduccionOctubre2015.ClientCertificates.Add(cert);
ProduccionOctubre2015.EnviarFacturaRequest facturaProduccionOctubre2015 = new ProduccionOctubre2015.EnviarFacturaRequest();

X509SecurityToken signatureToken = new X509SecurityToken(cert);

SoapContext requestContextProduccionOctubre2015 = proxyProduccionOctubre2015.RequestSoapContext;
requestContextProduccionOctubre2015.Security.Tokens.Add(signatureToken);
MessageSignature sig = new MessageSignature(signatureToken);
requestContextProduccionOctubre2015.Security.Timestamp.TtlInSeconds = 60;
requestContextProduccionOctubre2015.Security.Elements.Add(sig);
ProduccionOctubre2015.FacturaFile fraProduccionOctubre2015 = new ProduccionOctubre2015.FacturaFile();
facturaProduccionOctubre2015.correo = email;

string line = System.IO.File.ReadAllText(nombrefichero, Encoding.UTF8);

string line = System.IO.File.ReadAllText(nombrefichero, Encoding.UTF8);
string fichero64;
byte[] byt = System.Text.Encoding.UTF8.GetBytes(line);
fichero64 = Convert.ToBase64String(byt);
fraProduccionOctubre2015.factura = fichero64;
fraProduccionOctubre2015.nombre = "prueba.xsig";
fraProduccionOctubre2015.mime = "application/xml";
facturaProduccionOctubre2015.factura = fraProduccionOctubre2015;

try
{
ProduccionOctubre2015.EnviarFacturaResponse resultadoEnvioFacturaProduccionOctubre2015 =
new ProduccionOctubre2015.EnviarFacturaResponse();
string codRegistro = "";
string codigoSeguimiento = "";
string codigoResultado = "";
string descripcionResultado="";
resultadoEnvioFacturaProduccionOctubre2015 = proxyProduccionOctubre2015.enviarFactura(facturaProduccionOctubre2015);
codigoResultado=resultadoEnvioFacturaProduccionOctubre2015.resultado.codigo;
descripcionResultado=resultadoEnvioFacturaProduccionOctubre2015.resultado.descripcion;
codigoSeguimiento = resultadoEnvioFacturaProduccionOctubre2015.resultado.codigoSeguimiento;
codRegistro = (resultadoEnvioFacturaProduccionOctubre2015.factura == null) ? "" : resultadoEnvioFacturaProduccionOctubre2015.factura.numeroRegistro;
resultado.ok = true;
resultado.referenciaOk = codRegistro;
resultado.resultadoError = "";
if (codigoResultado.Trim() != "0")
{
//el codigo de resultado octubre 2015 es distinto de cero indica error
resultado.ok = false;
resultado.referenciaOk = "";
resultado.resultadoError = descripcionResultado;
}
}
catch (Exception ex)
{
string aviso = ex.Message;
Exception exProceso = ex;
resultado.ok = false;
resultado.referenciaOk = "";
resultado.resultadoError = aviso;
}
return resultado;
}


#35096
Posted: 11/24/2015 06:45:32
by Luis Concepcion (Standard support level)
Joined: 07/21/2007
Posts: 9

Hola

Gracias por la info, pero yo trabajo con Delphi, por lo que no sé donde podría hacer esos cambios que mencionas (instalar WSE 3 en el proyecto, etc.)

Un saludo
Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.

Reply

Statistics

Topic viewed 1071 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!