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

如何在JAXB中实现数字签名(Java + XAdES场景适用)

JAXB生成XML后添加XAdES数字签名实现方案

前置依赖

基于Java原生XML数字签名API + xades4j库实现,Maven依赖配置如下:

<dependency>
    <groupId>com.googlecode.xades4j</groupId>
    <artifactId>xades4j</artifactId>
    <version>1.6.0</version>
</dependency>

整体实现逻辑

不用修改原有JAXB编组逻辑,直接在JAXB生成XML的内存对象上附加签名即可,流程如下:

  • JAXB对象直接编组为DOM文档,避免文件IO开销
  • 加载密钥与证书信息
  • 配置XAdES签名参数
  • 执行签名并插入到XML指定位置
  • 输出签名后的XML文件

完整示例代码

1. JAXB对象转DOM文档

// 替换为你自己的JAXB根节点类
JAXBContext jaxbContext = JAXBContext.newInstance(YourRootClass.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

// 构造命名空间感知的DOM文档
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();
// 替换为你自己的JAXB实例对象
marshaller.marshal(yourJaxbRootObject, doc);

2. XAdES签名核心实现

import org.w3c.dom.Document;
import xades4j.production.XadesBesSigningProfile;
import xades4j.production.XadesSigner;
import xades4j.properties.DataObjectDesc;
import xades4j.properties.DataObjectReference;
import xades4j.properties.SignedDataObjects;
import xades4j.algorithms.EnvelopedSignatureTransform;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

// 加载密钥库,示例用JKS格式,可替换为PKCS12等其他格式
KeyStore ks = KeyStore.getInstance("JKS");
try(FileInputStream fis = new FileInputStream("your_keystore_path.jks")) {
    ks.load(fis, "your_keystore_password".toCharArray());
}
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(
    "your_key_alias",
    new KeyStore.PasswordProtection("your_key_password".toCharArray())
);
X509Certificate signingCert = (X509Certificate) keyEntry.getCertificate();
PrivateKey signingKey = keyEntry.getPrivateKey();

// 初始化XAdES-BES签名配置,可根据需求替换为XAdES-T等其他格式
XadesBesSigningProfile signingProfile = new XadesBesSigningProfile(keyEntry);
XadesSigner signer = signingProfile.newSigner();

// 配置签名范围:空URI代表签名整个文档,如需签名特定节点改为`#nodeId`即可
DataObjectDesc signedObject = new DataObjectReference("")
    .withTransform(new EnvelopedSignatureTransform());
SignedDataObjects signedDataObjects = new SignedDataObjects(signedObject);

// 执行签名,默认插入到根节点下,可传入指定DOM节点修改插入位置
signer.sign(signedDataObjects, doc.getDocumentElement());

// 输出签名后的XML文件
Transformer transformer = TransformerFactory.newInstance().newTransformer();
try(FileOutputStream fos = new FileOutputStream("signed_output.xml")) {
    transformer.transform(new DOMSource(doc), new StreamResult(fos));
}

常见调整说明

  • 密钥来源可根据业务场景替换为UKey、云KMS等其他存储方式,只需正确获取PrivateKey和对应签名证书即可
  • 如需添加时间戳扩展为XAdES-T格式,只需在签名Profile中配置时间戳服务地址即可
  • 如遇到加密算法不支持报错,可升级JDK版本或替换JCE无限制权限政策文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:09:03