如何避免Tomcat8.5+JDK8环境下XMLSignature生成多余的 (CR)
解决Java XMLSignature生成后SignatureValue/X509Certificate含
的问题
你遇到的问题是XML签名生成时,Base64编码的SignatureValue和X509Certificate内容里的换行符被转义成了 ,这通常是XML输出阶段的换行符处理逻辑导致的。以下是几种可行的解决思路:
1. 调整XML Transformer的输出属性(推荐)
在将签名后的DOM文档写入输出流时,显式设置Transformer的换行符属性,避免CR(回车符)被转义:
TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); // 启用缩进(可选,按需开启) transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); // 设置换行符为LF,避免CR被转义成 transformer.setOutputProperty(OutputKeys.LINE_SEPARATOR, "\n"); // 执行转换写入 transformer.transform(new DOMSource(signedDoc), new StreamResult(new FileOutputStream("signed.xml")));
2. 直接设置Apache XML Security的换行忽略配置
如果系统属性未生效,尝试在XML Security初始化前直接调用API配置:
// 先初始化XML Security库 org.apache.xml.security.Init.init(); // 强制忽略换行符处理 org.apache.xml.security.utils.XMLSecurityProperties.setIgnoreLineBreaks(true); // 后续执行签名生成逻辑 XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM"); // ... 你的签名创建、签署代码
注意:如果使用JDK内置的com.sun.org.apache.xml.internal.security包,需确保系统属性在加载相关类之前设置(比如放在main方法最开头),否则配置可能不生效。
3. 临时修复:手动清理转义字符
如果上述方法无法快速生效,可以在生成XML后手动替换 :
// 将DOM转换为字符串 StringWriter sw = new StringWriter(); TransformerFactory.newInstance().newTransformer().transform(new DOMSource(signedDoc), new StreamResult(sw)); String xmlContent = sw.toString(); // 移除所有 转义符 xmlContent = xmlContent.replace(" ", ""); // 写入目标文件 Files.write(Paths.get("signed.xml"), xmlContent.getBytes(StandardCharsets.UTF_8));
这种方法属于临时 workaround,建议优先从XML生成的根源解决问题。
内容的提问来源于stack exchange,提问作者iambenna
相关产品推荐
相关产品推荐

