我正在墨西哥使用电子发票,要取消发票,您必须发送一个用 certificate.cer 和 key.key 签名的 xml,问题是在签署 XML 时,它是用换行符生成的。
如果我在签署 XML 后删除这些换行符,则印章将失效。
如果我发送带有换行符的 xml,它们会响应换行符生成的错误。
这是我生成签名的代码
*我正在使用 javax.xml.crypto API 生成签名
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
X509Certificate cert = KeyLoaderFactory.createInstance(KeyLoaderEnumeration.PUBLIC_KEY_LOADER, new FileInputStream("C:\\Users\\Arturo\\Desktop\\PEMS\\Certificado\\00001000000201052508s.cer")).getKey();
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerDN().getName(), cert.getSerialNumber());
x509Content.add(issuer);
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new FileInputStream("C:\\Users\\Arturo\\Documents\\NetBeansProjects\\AdminFraccionamientoWeb1\\web\\assets\\Pdfs\\Cancel_" + UUID + ".xml"));
PrivateKey privateKey = KeyLoaderFactory.createInstance(KeyLoaderEnumeration.PRIVATE_KEY_LOADER, new FileInputStream("C:\\Users\\Arturo\\Desktop\\PEMS\\Certificado\\DST1010185B7_1205102226S.key"), "Soporte1").getKey();
DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
String Ruta = "C:\\Users\\Arturo\\Documents\\NetBeansProjects\\AdminFraccionamientoWeb1\\web\\assets\\Pdfs\\Cancel_signed" + UUID + ".xml";
OutputStream os = new FileOutputStream(Ruta);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
这是为我生成此代码的 XML
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>DiLnrOczxtHVnhG4EA9zj0JM8O0=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>PrHxWCpnZlFi92ETs0JMnVML/FoUxQkktRT5UpU9W90DhKZFX31nFjwEtt3GBluz+xEdt+j4lmnd
JHdZbEynVwqsm5ZF2Y/Z34fn/f050pUXyjitlog8QWoKB+oCbaNW1L3+9VHyuKQ4t/1XbNt6RCgM
RkDEm4hDc6V55G/szIQ=
</SignatureValue>
<KeyInfo>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>OID.1.2.840.113549.1.9.2=Responsable: Cecilia Guillermina García Guerra, OID.2.5.4.45=SAT970701NN3, L=Cuauhtémoc, ST=Distrito Federal, C=MX, OID.2.5.4.17=06300, STREET="Av. Hidalgo 77, Col. Guerrero", [email protected], OU=Administración de Seguridad de la Información, O=Servicio de Administración Tributaria, CN=A.C. del Servicio de Administración Tributaria
</X509IssuerName>
<X509SerialNumber>275106190557734483187066766774039086286478061624
</X509SerialNumber>
</X509IssuerSerial>
<X509Certificate>
MIIErTCCA5WgAwIBAgIUMDAwMDEwMDAwMDAyMDEwNTI1MDgwDQYJKoZIhvcNAQEFBQAwggGVMTgw
NgYDVQQDDC9BLkMuIGRlbCBTZXJ2aWNpbyBkZSBBZG1pbmlzdHJhY2nDs24gVHJpYnV0YXJpYTEv
MC0GA1UECgwmU2VydmljaW8gZGUgQWRtaW5pc3RyYWNpw7NuIFRyaWJ1dGFyaWExODA2BgNVBAsM
L0FkbWluaXN0cmFjacOzbiBkZSBTZWd1cmlkYWQgZGUgbGEgSW5mb3JtYWNpw7NuMSEwHwYJKoZI
hvcNAQkBFhJhc2lzbmV0QHNhdC5nb2IubXgxJjAkBgNVBAkMHUF2LiBIaWRhbGdvIDc3LCBDb2wu
IEd1ZXJyZXJvMQ4wDAYREVMRDAUwNjMwMDELMAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRv
IEZlZGVyYWwxFDASBgNVBAcMC0N1YXVodMOpbW9jMRUwEwYDVQQtEwxTYYQ5NzA3MDFOTjMxPjA8
BgkqhkiG9w0BCQIML1Jlc3BvbnNhYmxlOiBDZWNpbGlhIEd1aWxsZXJtaW5hIEdhcmPDrWEgR3Vl
cnJhMB4XDTEyMDUxMTAzMzYyNloXDTE2MDUxMTAzMzYyNlowge4xMDAuBgNVBAMTJ0RFU0FSUk9M
TE9TIFkgU09MVUNJT05FUyBFTiBUSSBTQSBEIUJGVjEwMC4GA1UEKRMnREVTQVJST0xMT1MgWSBT
T0xVQ0lPTkVTIEVGFERLIFNBIERFIENWMTAwLgYDVQQKEydERVNBUlJPTExPUyBZIFNPTFVDSU9O
RVMgRU4gVEkgU0EgREUgQ1YxJTAjBgNVBC0THERTVDEwMTAxODVCNyAvIFJJSk82OTA1MDhUQzEx
HjAcBgNVBAUTFSAvIFJJWEo2OTA1MDhIWlNTWFIwNjEPMA0GA1UECxMGVW5pZGFkMIGfMA0GCSqG
SIb3DQEBAQUAA4GNADCBiQKBgQDQZhQqxDy8Z05TPsl+jWl02mufOmhO2gyfQ2fNyCdbdjDDX3Ro
yp/23TYv6GiITJrsnUrEgDN6WrFIyS906GvyUvzQ8yTDwJPcS3PPLeybKr45PQIs06pyX70bNCEa
hJE3Afx+0YxfgQcw4QuSJ3Gr0mQT1A7/N0Ol33iQgtTLeQIDAQABox0wGzAMBgNVHRMBAf8EAjAA
MAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQUFAAOCAQEAbkjSi+DlMH69RK7fFXDLvZYUX+4gvutp
X2ex4LU/qFZVw7lvIYWITeUqF2DmuRzNXKNQqgSSRwuOnU0/ipxjR9JL0JIlLgy71nMtwMyQUO8q
Ei/EihXg1XHtOvPSsnFigRunD8ziyDpz+2ozUZS969zjRbsve9J5J2ke3CirrIjOLQaYbWBngrdl
8pXJPaaElkB5ZwzRKAP94P14WPOioTSmkBbhChEJ6xZKFcDRySRfWAsXmss9CvBM3nMqPhFdw2kj
6Rr/NsST5PZtp5Olk1xBhrPj5MVTZmzLpDvTz6+wFwrn5ucrIkUL+Uk4ZGD0HnTZYEeCh+VPeyXe
Er5fAw==
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
如您所见,生成的 xml 有换行符(不需要)。
我会很感激任何帮助,谢谢。
经过几个小时的研究,我找到了解决问题的方法,我希望它会对某人有所帮助。
我们只需将值分配给
true
参数ignoreLineBreaks
,因为默认情况下,它的值false
允许在签署 XML 文档时添加换行符。这是防止添加换行符的代码:
然后我们可以使用以下行检查该值是否已正确分配:
尝试使用该属性
OutputKeys.INDENT
: