You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apache Santuario验证加密XML签名失败,如何禁用解密?

问题解决:Apache Santuario+StAX仅验证加密XML的签名而不解密

核心问题原因

你使用InboundXMLSec.processInMessage时,即便只指定了SIGNATURE动作,Apache Santuario的默认处理逻辑仍会解析XML中的加密节点并尝试自动解密——这是因为该API设计用于完整的Web服务安全消息处理,默认会处理所有安全相关节点。而你的签名是基于加密后的原始内容生成的,解密后内容变更导致摘要验证失败;同时未设置解密密钥时,会触发API的必填项校验异常。

解决方案:手动定位签名节点并单独验证

跳过自动消息处理流程,直接遍历XML流找到签名节点,使用StAXSignatureValidator单独验证签名,完全无需处理解密逻辑。

调整后的代码示例

import org.apache.xml.security.stax.ext.SignatureValidator;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamConstants;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PublicKey;

public class SignatureValidationOnly {
    public static void main(String[] args) throws Exception {
        // 加载密钥库,获取签名验证公钥
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new FileInputStream("path/to/store.jks"), "secret".toCharArray());
        PublicKey verificationKey = (PublicKey) ks.getCertificate("test.name").getPublicKey();

        // 初始化XML流读取器
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream("path/to/encrypted-signed.xml"));

        // 遍历流,定位到DSig签名节点
        while (xmlStreamReader.hasNext()) {
            int event = xmlStreamReader.next();
            if (event == XMLStreamConstants.START_ELEMENT 
                && "Signature".equals(xmlStreamReader.getLocalName())
                && "http://www.w3.org/2000/09/xmldsig#".equals(xmlStreamReader.getNamespaceURI())) {
                break;
            }
        }

        // 初始化并执行签名验证
        StAXSignatureValidator validator = new StAXSignatureValidator(xmlStreamReader);
        validator.setVerificationKey(verificationKey);
        
        boolean isValid = validator.validate();
        if (isValid) {
            System.out.println("签名验证通过");
        } else {
            System.out.println("签名验证失败");
        }

        // 关闭资源
        xmlStreamReader.close();
    }
}

关键注意事项

  • 确保你的签名是针对加密后的XML内容生成的:如果签名引用的是加密前的明文内容,那么必须解密才能验证,这种场景下无法绕过解密步骤。
  • 避免用InboundXMLSec处理单一签名验证需求:该API更适合包含多种安全操作(签名+加密+身份认证等)的完整WS-Security消息处理,单一签名验证用StAXSignatureValidator更直接。

内容的提问来源于stack exchange,提问作者ylr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 06:11:12