我遇到了格式化XML签名的问题。当我对对象进行序列化时,我指定了缩进。结果XML包含缩进和换行符。后来,我签署了XML,但是在反序列化Document对象的那一刻,我再次对结果String应用了缩进(这是正确的吗?)。结果XML签名的验证失败。当我在不应用任何格式的情况下处理xml时,不会发生这种情况。对于这种情况,签名验证成功。
是的,解决方案是签署XML而不格式化它。但这不是我案例的解决方案。
请帮帮我。这是我的代码:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
InputStream stream = new ByteArrayInputStream(
myXmlString.getBytes("UTF-8"));
Document doc = builder.parse(stream);
KeyStore ks = getKeyStore();
PrivateKey privateKey = (PrivateKey) ks.getKey(my_key_alias,
new String(mykey_password).toCharArray());
Certificate cert = ks.getCertificate(my_certificate_alias);
PublicKey publicKey = cert.getPublicKey();
DOMSignContext dsc = new DOMSignContext(privateKey,
doc.getDocumentElement());
dsc.putNamespacePrefix("http://www.w3.org/2000/09/xmldsig#", "ds");
dsc.setDefaultNamespacePrefix("ds");
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_WITH_COMMENTS,
(C14NMethodParameterSpec) null), fac
.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));
KeyInfoFactory kif = fac.getKeyInfoFactory();
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks
.getEntry(my_key_aliass, new KeyStore.PasswordProtection(
my_key_password.toCharArray()));
X509Certificate certX509 = (X509Certificate) keyEntry.getCertificate();
List x509Content = new ArrayList();
x509Content.add(certX509.getSubjectX500Principal().getName());
x509Content.add(certX509);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);
对象的反序列化
OutputFormat format = new OutputFormat(doc);
format.setLineWidth(200);
format.setIndent(4);
StringWriter stringOut = new StringWriter();
XMLSerializer serial = new XMLSerializer(stringOut, format);
serial.serialize(doc);
//XML WITH THE SIGNATURE
return stringOut.toString();
在哪里可以指定要签名的XML是否有缩进和换行符?
我使用XMLSerializer,因为在尝试使用XERCES 2.4.0的Transform时遇到了版本控制问题。我无法更新xerces API。
非常感谢任何形式的帮助。
提前致谢!