当前位置: 首页 > 知识库问答 >
问题:

使用xmldsig签名的JAXB编组

曾嘉福
2023-03-14

有没有可能创建jaxb编组器,它可以自动将数字签名添加到xml内容中。

例如,如果我有一个定义为:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {
    @XmlElement
    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

我的xml由marshaller生成,看起来像:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><test><info>value</info></test>

我希望它看起来像:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Security>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
                <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"/>
                <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                <Reference URI="">
                    <Transforms>
                        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envelopedsignature"/>
                    </Transforms>
                    <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                    <DigestValue>4432kZ6c2JPwP3A=</DigestValue>
                </Reference>
            </SignedInfo>
            <SignatureValue>Mvbd4603knhh2LZTyE1MIiEF7N46b7GoTzxsqs5eyIXYNG96MFPIMo+P6okzIPzRKrL2obpf3V4D/F0gw5vM/UJwb2MvrCo/5JM5qvV0f09dzWLrgkPyShiQnFL2vzECwmMOrCA=</SignatureValue>
            <KeyInfo>
                <X509Data>
                        <X509Certificate>MIIEnjCCBAegAwIBAgIDJQDMA0GCSqGSICBMGSETU0VOMRgwFgYDVQQHEw82NTAwOCBXaWVzYmFkZW4xGjAYBgNVBkESE9MRElORyBBRzEiMCAGA1UEAxMZSW50ZXJuZXQgQmVudXR6ZXIgU2VydmljZTEqMCgGCSqGSIb3DQEJARbeVydmaWthdEBzY2h1ZmEtb25saW5lLmRlMB4XDTA5MDcyNzEwNTkyNVoXDTEwMDcyNzEwNTkyNVowgZsxCzAJdNVBATAkFMQLmRlMCYGfUdEgQfMB2BG3plcnRpZmlrYXRAc2NodWZhLW9ubGluZS5kZTAfsgkqhkiG9w0BAQQFAAOBgQB7DBly8bqksxrkwcmN2A/xfu3lm0IfGD6PoJ7JFgPq4aHBDWgdUW3EzvRE+cuFGjkoBvATKfcbF7ReTz+4C+dLJShYiN/HxUnxgiO7R2y4c/I4pNnmlfQT261/dNlQ8Wm8pyUeMcr32fxvtoY4dqlQy7GePmrHpR3HE/dMRAd6gA==</X509Certificate>
                </X509Data>
                <KeyValue>
                    <RSAKeyValue>
                        <Modulus>1EN/UxtM2fLYxxDmSxgjSd10AzCxvZtNGAER9j3+OMqZjBXG9uLiZR+GbtOXbsDz3fyiwEfu/FDeeGGESppYAL5foQ72t2ztV5w2GLtTH0K+wrlImmvoTdl6bsdC7RXAsXVxtlkoG0xL7HGwZLvM=</Modulus>
                        <Exponent>AQAB</Exponent>
                    </RSAKeyValue>
                </KeyValue>
            </KeyInfo>
        </Signature>
    </Security>
<test><info>value</info></test>

我希望有办法通过马歇尔做到这一点?如果没有,也许还有其他简单的方法来签署xml?

提前致谢

共有1个答案

太叔经赋
2023-03-14

您需要使用JAXB将域模型列表到DOMDocument,然后使用如下方法将签名应用到该模型:

import java.security.*;
import java.util.Collections;
import javax.xml.bind.*;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Test.class);

        Test test = new Test();
        test.setInfo("value");

        Marshaller marshaller = jc.createMarshaller();
        DOMResult domResult = new DOMResult();
        marshaller.marshal(test, domResult);

        String providerName = System.getProperty("jsr105Provider",
                "org.jcp.xml.dsig.internal.dom.XMLDSigRI");

        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                (Provider) Class.forName(providerName).newInstance());

        Reference ref = fac.newReference("", fac.newDigestMethod(
                DigestMethod.SHA1, null), Collections.singletonList(fac
                .newTransform(Transform.ENVELOPED, (XMLStructure) null)), null,
                null);

        SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(
                CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (XMLStructure) null), fac
                .newSignatureMethod(SignatureMethod.DSA_SHA1, null),
                Collections.singletonList(ref));

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
        kpg.initialize(512);
        KeyPair kp = kpg.generateKeyPair();

        KeyInfoFactory kif = fac.getKeyInfoFactory();
        KeyValue kv = kif.newKeyValue(kp.getPublic());

        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

        Document doc = (Document) domResult.getNode();

        DOMSignContext dsc = new DOMSignContext(kp.getPrivate(),
                doc.getDocumentElement());

        XMLSignature signature = fac.newXMLSignature(si, ki);
        signature.sign(dsc);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        DOMSource source = new DOMSource(domResult.getNode());
        StreamResult result = new StreamResult(System.out);
        t.transform(source, result);
    }

}
 类似资料:
  • 我需要使用java.security包使用信封的xml-dsig签名来验证文档。加载后,我取消了元帅文档,并根据xsd具有签名对象 - http://www.w3.org/2000/09/xmldsig# 然后: 调用getPublicKey并验证,结果我得到了签名长度不匹配,如果我没有编码签名,我没有得到不匹配,但也验证是错误的,但我使用的测试数据是完全有效的。放弃寻找错误,帮助我。请。文件编码

  • 问题内容: 我正在使用Jersey和JAXB构建简单的RESTful Web服务,我将HashMap从’String’转换为’Integer’: 我需要生成一个如下所示的XML响应: 用JAXB生成动态标签名的最佳方法是什么? 问题答案: 您可以使用-annotated属性并将元素返回为s: 这种方法很丑陋,但比它产生的XML丑陋。

  • 这是我的xml,需要把它转换成Java。我使用了jaxb 并抛出以下异常javax.xml.bind.unmarshalException:意外元素(URI:“http://www.ae.com/event/load”,local:“order”)。需要的元素为<{}LM:order>

  • 我已经阅读了这里的文章和在使用JAXB时处理数字签名的示例代码,并且遇到了一个问题,我认为是JAXB封送将名称空间引入“signedinfo”元素。 我定义了一个XSD,它将被用不同编程语言实现的多个应用程序使用。我将XSD编译为JAXB注释类,供我的实现(Jersey JAX-RS和JAX-WS)使用。我目前拥有的流量如下: JAXB对象使用适当的数据创建或从远程应用程序传递。 按照Blaise

  • 问题内容: 我正在构建一系列链接的类,我希望它们的实例能够编组到XML,以便可以将它们保存到文件中并在以后再次读取。 目前,我正在使用以下代码作为测试用例: XML输出为: 元素为空是否有原因?我希望它包含日期(即)的字符串表示形式。为此,我是否需要编写自己的代码? 输出为: 问题答案: 您将必须创建一个这样的: 并使用 另请参阅是否要在程序包级别定义适配器。

  • 假设我有这样的xml: 签名后我得到: 事实上,