使用xmldsig签名的JAXB编组

是否可以创建jaxb marshaller,它自动将数字签名添加到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; } } 

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

 value 

我希望它看起来像:

            4432kZ6c2JPwP3A=   Mvbd4603knhh2LZTyE1MIiEF7N46b7GoTzxsqs5eyIXYNG96MFPIMo+P6okzIPzRKrL2obpf3V4D/F0gw5vM/UJwb2MvrCo/5JM5qvV0f09dzWLrgkPyShiQnFL2vzECwmMOrCA=   MIIEnjCCBAegAwIBAgIDJQDMA0GCSqGSICBMGSETU0VOMRgwFgYDVQQHEw82NTAwOCBXaWVzYmFkZW4xGjAYBgNVBkESE9MRElORyBBRzEiMCAGA1UEAxMZSW50ZXJuZXQgQmVudXR6ZXIgU2VydmljZTEqMCgGCSqGSIb3DQEJARbeVydmaWthdEBzY2h1ZmEtb25saW5lLmRlMB4XDTA5MDcyNzEwNTkyNVoXDTEwMDcyNzEwNTkyNVowgZsxCzAJdNVBATAkFMQLmRlMCYGfUdEgQfMB2BG3plcnRpZmlrYXRAc2NodWZhLW9ubGluZS5kZTAfsgkqhkiG9w0BAQQFAAOBgQB7DBly8bqksxrkwcmN2A/xfu3lm0IfGD6PoJ7JFgPq4aHBDWgdUW3EzvRE+cuFGjkoBvATKfcbF7ReTz+4C+dLJShYiN/HxUnxgiO7R2y4c/I4pNnmlfQT261/dNlQ8Wm8pyUeMcr32fxvtoY4dqlQy7GePmrHpR3HE/dMRAd6gA==    1EN/UxtM2fLYxxDmSxgjSd10AzCxvZtNGAER9j3+OMqZjBXG9uLiZR+GbtOXbsDz3fyiwEfu/FDeeGGESppYAL5foQ72t2ztV5w2GLtTH0K+wrlImmvoTdl6bsdC7RXAsXVxtlkoG0xL7HGwZLvM= AQAB      value 

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

提前致谢

您需要使用JAXB将域模型编组为DOM Document ,然后使用如下方法将签名应用于该模型:

 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); } }