luisgoncalves / xades4j

A Java library for XAdES signature services
GNU Lesser General Public License v3.0
110 stars 65 forks source link

\&\#13; character in ds:SignatureValue and ds:X509Certificate values #189

Closed jerojasol closed 5 years ago

jerojasol commented 5 years ago

Hi, I'm signing a xml document with xades4j library, and it works fine. But on the resulting XML the X509Certificate looks something like this:

<ds:X509Certificate>
MIIIPTCCBiWgAwIBAgIIAoRXE3mPJR0wDQYJKoZIhvcNAQELBQAwgbQxIzAhBgkqhkiG9w0BCQEW&#13;
FGluZm9AYW5kZXNzY2QuY29tLmNvMSMwIQYDVQQDExpDQSBBTkRFUyBTQ0QgUy5BLiBDbGFzZSBJ&#13;
STEwMC4GA1UECxMnRGl2aXNpb24gZGUgY2VydGlmaWNhY2lvbiBlbnRpZGFkIGZpbmFsMRMwEQYD&#13;
VQQKEwpBbmRlcyBTQ0QuMRQwEgYDVQQHEwtCb2dvdGEgRC5DLjELMAkGA1UEBhMCQ08wHhcNMTgx&#13;
MDAxMDgwMDAwWhcNMTkxMDAxMDc1OTAwWjCCAQMxLzAtBgNVBAkMJkNhbGxlIDY5ICA0IC0gNDgg&#13;
T2ZpY2luYSA0MDQgQnVyw7MgNDA0MScwJQYJKoZIhvcNAQkBFhhqYXZpZXJyaW5jb25AZmFjdHVy&#13;

and the signature value looks like this:

<ds:SignatureValue Id="xmldsig-bd502225-dd30-4729-bf0d-24c96d899cb4-sigvalue">
fkwofUxqw/iRQ+gPHzS7j4HYUm1a4mgMr62YAgZb5FIJpcgYUIajV3uf9YCRA6mOQLTp/fgtYm8U&#13;
VSVLIFhTQdSjVNXodiQBvly8xoe1la7gh4oTjbNnOcKCkVKw+zjkIhcj57aJji/nrl8yvJ6OObbh&#13;
1uUAEHlClnMSt3omwbd+B8wM220wjcOCwjLs6va3JYOtvwdwB91EYUcEl3nCtSSgxV+ds9d5Wl0N&#13;
UbePsRZUYjU7K67AIBHDlm8/tRmlOpo6WA07XjGvp6Dg1pHQyv+zfAjghvjJGHd+mCZcbJqGdpo3&#13;
bY0BfJLwuB/B2N/hGFRixGeWLnFh1v+zPPkuJw==
</ds:SignatureValue>

How can I remove the "& #13;" from it?, my receiver (DIAN - Colombia) says they can't validate the signature for it, thanks in advance.

luisgoncalves commented 5 years ago

Hi. That sounds like a problem with encodings in your code. Recently there was a user reporting a similar issue and he managed to solve the problem on his code: #186. Take a look at that thread and see if it helps,.

geflodu commented 5 years ago

@luisgoncalves I have tried changing the transformer to transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, ENCODING); where ENCODING= "ISO-8859-1" but the error persists, @jerojasol algun avance con este error?

angelcantu84 commented 5 years ago

Hi @geflodu the codification &#13 is the correct way to make a XML with UTF-8 encoding, if you want to delete this codification you can exchange this with a "\n". Because &#13 is a "\r"

Regards

angelcantu84 commented 5 years ago

@jerojasol hola colega, puedo ayudarte con tu problema pero te comento que no es necesario quitar esa codificacion ya que el problema no es ese, es otro... la DIAN esta hecha un desastre ahorita. Te invito a contactarme al correo siegroupmx [a] gmail com para compartir informacion

The codification &#13 is not the problem, the problem is the internal process at DIAN because may be have a old version of xades4j, or I don't know, but this codification &#13 in the XMLs is the correct way to make the XML, if you see the oficial example on this library --> https://github.com/luisgoncalves/xades4j/blob/master/src/test/xml/document.signed.epes_2.xml

The codification &#13 is present...

geflodu commented 5 years ago

Hi @geflodu the codification &#13 is the correct way to make a XML with UTF-8 encoding, if you want to delete this codification you can exchange this with a "\n". Because &#13 is a "\r"

Regards

Aún así no logro que sea valido para la DIAN, que configuración debo usar para poder pasar el filtro de validación de firma? la verdad he intentado varias cosas pero aún no logro pasar esto

jerojasol commented 5 years ago

Hola @angelcantu84 efectivamente ese no era el problema, ya de nuevo me está aceptando los documentos, básicamente lo que hice fue seguir este hilo que me sugerió @luisgoncalves : #186, ahí se encuentra un ejemplo de como realizar la firma, aunque es muy parecida a la versión que yo tenia y ya me funcionaba, use esta tal cual y con esta ya me acepta documentos de nuevo, sin embargo si me gustaría que estuviéramos en contacto para cualquier cosa que se pueda presentar en el futuro, @geflodu prueba con este código que fue el que baje del hilo que menciono, cualquier cosa me puedes escribir a jorge.rojas@algocodex.com, quedo atento. FirmaElectronica.java.txt

angelcantu84 commented 5 years ago

@jerojasol y @geflodu Seria bueno unir fuerzas :D, ya que el UBL 2.1 viene al asecho... Les dejo mi correo: angel.cantu@sie-group.net me encantaría estemos en contacto para intercambiar experiencias y apoyo mutuo.

luisgoncalves commented 5 years ago

I'm assuming that the problem is similar to #186, i.e. probably not the escape characters but some other issue on the code, such as mangling with strings/encodings/etc.

P.S.: people submitting signatures for DIAN, please search on the closed issues for "DIAN", as I've added it on the titles of the issues that contain the best information on how to configure xades4j for that purpose.

FE-H commented 5 months ago

Hi @luisgoncalves, I am currently trying out this library to fit the Malaysian E-Invoice mandate. There is no working validator currently from the tax authority. I have tried the solution from #186. The escape for /N persists in 2.2.2 at EncapsulatedTimeStamp section. Any advice to correct if required by the tax authority? `
static { System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true"); }

public static void main(String[] args) throws Exception {
    System.out.println("______________________");
    System.out.println("\tSign");
    System.out.println("______________________");
    exampleXAdES4J_Imp.signTBes();

    System.out.println("______________________");
    System.out.println("\tVerify");
    System.out.println("______________________");
    //verifyBes();

}
private static void signTBes() throws Exception {

    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(UNSIGNED));
    Element elem = doc.getDocumentElement();
    DOMHelper.useIdAsXmlId(elem);
    Node e = doc.getChildNodes().item(0).getChildNodes().item(0).getChildNodes().item(0).getLastChild().getChildNodes().item(0).getChildNodes().item(0);

    FileSystemKeyStoreKeyingDataProvider kdp = FileSystemKeyStoreKeyingDataProvider.builder("pkcs12",CERT_FOLDER+CERT,KeyStoreKeyingDataProvider.SigningCertificateSelector.single()).storePassword(new exampleXAdES4J_Imp.DirectPasswordProvider("")).entryPassword(new DirectPasswordProvider("")).fullChain(true).build();
    SignatureAlgorithms algorithms = new SignatureAlgorithms().
                                                withCanonicalizationAlgorithmForSignature(new GenericAlgorithm(Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS)).
                                                withSignatureAlgorithm("RSA", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256);

    XPathTransform xPath1 = new XPathTransform("not(//ancestor-or-self::ext:UBLExtensions)").withNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2");
    XPathTransform xPath2 = new XPathTransform("not(//ancestor-or-self::cac:Signature)").withNamespace("cac","urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2");

    //KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider("pkcs12",CERT_FOLDER + CERT,new FirstCertificateSelector(),new DirectPasswordProvider(PASS),new DirectPasswordProvider(PASS),true);
    DataObjectDesc obj = new DataObjectReference("").withTransform(xPath1).withTransform(xPath2).withDataObjectFormat(new DataObjectFormatProperty("text/xml"));
    SignedDataObjects dataObjs = new SignedDataObjects().withSignedDataObject(obj);

    XadesSigner signer = new XadesTSigningProfile(kdp).withSignatureAlgorithms(algorithms).with(new HttpTsaConfiguration("https://freetsa.org/tsr")).newSigner();
    //signer.sign(dataObjs, elem);
    signer.sign(dataObjs, e, SignatureAppendingStrategies.AsLastChild);

    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "no");
    DOMSource source = new DOMSource(doc);
    OutputStream os = new ByteArrayOutputStream();
    StreamResult result = new StreamResult(os);
    transformer.transform(source, result);

    System.out.print(os);
}`

image Output from the code, pretty printed in Notepad++.

luisgoncalves commented 5 months ago

The encoding should work, as it's a correct way to encode a new line. That said, can you try starting Java with the system property, instead of setting it in code?

Also, try the following system property: com.sun.org.apache.xml.internal.security.ignoreLineBreaks=true

FE-H commented 5 months ago

image The &#13 persists after setting the variables at VM args run configuration. Will observe and reach out if we eventually run into issues. Thanks!