使用XPathTransform对UBL2.1做xades4j签名时摘要无效如何解决
问题原因
- 未注册命名空间:XPath表达式中使用的
ext、cac、cbc等前缀没有绑定对应的UBL命名空间URI,XPath解析器无法正确匹配目标节点,过滤逻辑完全失效。 - XPathTransform使用方式错误:多次独立添加XPathTransform的逻辑并非叠加过滤,反而会导致节点集计算出现偏差,不符合预期。
- 缺少规范化变换:XML签名要求先对内容执行规范化处理,消除空格、换行等格式差异,未添加该步骤也会导致摘要计算结果无效。
解决方案
优先使用XPath Filter 2.0变换,这是W3C专门为XML签名节点过滤场景设计的标准,处理更准确、性能更好,配置示例如下:
import xades4j.production.DataObjectDesc; import xades4j.production.DataObjectReference; import xades4j.properties.DataObjectFormatProperty; import xades4j.transforms.CanonicalXML10Transform; import xades4j.transforms.XPath2FilterTransform; import java.util.Map; DataObjectDesc obj = new DataObjectReference("") // 先添加XML规范化变换,必选步骤 .withTransform(new CanonicalXML10Transform()) // 排除ext:UBLExtensions节点 .withTransform( new XPath2FilterTransform( "//ext:UBLExtensions", XPath2FilterTransform.FilterType.SUBTRACT, Map.of("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2") ) ) // 排除cac:Signature节点 .withTransform( new XPath2FilterTransform( "//cac:Signature", XPath2FilterTransform.FilterType.SUBTRACT, Map.of("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2") ) ) // 排除ID为QR的cac:AdditionalDocumentReference节点 .withTransform( new XPath2FilterTransform( "//cac:AdditionalDocumentReference[cbc:ID='QR']", XPath2FilterTransform.FilterType.SUBTRACT, Map.of( "cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2", "cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" ) ) ) .withDataObjectFormat(new DataObjectFormatProperty("text/xml"));
如果必须使用旧版XPathTransform,需合并过滤条件并注册所有用到的命名空间,配置示例如下:
import xades4j.production.DataObjectDesc; import xades4j.production.DataObjectReference; import xades4j.properties.DataObjectFormatProperty; import xades4j.transforms.CanonicalXML10Transform; import xades4j.transforms.XPathTransform; import java.util.Map; // 合并三个排除条件为单个XPath表达式 String filterXpath = "not(ancestor-or-self::ext:UBLExtensions) and not(ancestor-or-self::cac:Signature) and not(ancestor-or-self::cac:AdditionalDocumentReference[cbc:ID='QR'])"; // 注册所有用到的命名空间前缀和对应URI Map<String, String> nsMapping = Map.of( "ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2", "cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2", "cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" ); DataObjectDesc obj = new DataObjectReference("") .withTransform(new CanonicalXML10Transform()) .withTransform(new XPathTransform(filterXpath, nsMapping)) .withDataObjectFormat(new DataObjectFormatProperty("text/xml"));
内容的提问来源于stack exchange,提问作者user2769843
相关产品推荐
相关产品推荐

