我正在使用墨西哥“factura Electronica”,我需要使用cert.cer和key.key文件签署XML文档,
但要求是标签之间绝对没有空格和换行符,包括签名标签()。
如果我在签名后删除换行符和空格,签名就会被破坏, 我也无法更改规范化器/变换器组,因为它们是预定义的。
*我正在使用javax.xml.crypto API签署XML文档
以下是代码:
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\\0000166600201052508s.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_1205106666S.key"), "Suport").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));
以下是生成的签名
<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", EMAILADDRESS=asisnet@sat.gob.mx, 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>
注意不需要的换行符。
非常感谢任何帮助。
答案 0 :(得分:1)
几个小时后,我找到了解决问题的方法。 我希望这适用于其他人。
我们只需要将“true”值设置为“ignoreLineBreaks”参数, 导致'默认值为false,这允许签名API添加LineBreaks
这是避免或删除LineBreaks的代码
Field f = XMLUtils.class.getDeclaredField("ignoreLineBreaks");
f.setAccessible(true);
f.set(null, Boolean.TRUE);
然后,我们可以使用下一个代码行确保新值为true
System.err.println(XMLUtils.ignoreLineBreaks());
答案 1 :(得分:0)
您可以使用文本编辑器(如Notepad ++)轻松删除任何空格,包括换行符,制表符和换行符等。下面是一个快照,显示可用于删除这些空格的扩展字符。 Replace tab in notepad++ text editor