gpt4 book ai didi

java - 如何在 Java 中移动签名 XML 中的签名节点

转载 作者:行者123 更新时间:2023-11-30 10:56:56 26 4
gpt4 key购买 nike

我有这个 XML 示例。我需要的是用 Java 签署 xml。问题是我在错误的地方得到了“签名”节点..

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fu="http://www.fu.gov.si/" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">
<soapenv:Body>
<fu:BusinessPremiseRequest Id="data">
<fu:Header>
<fu:MessageID>20DF8D44-ABBE-76BA-E053-AA02010AEA8E</fu:MessageID>
<fu:DateTime>2015-09-24T12:07:28</fu:DateTime>
</fu:Header>
<fu:BusinessPremise>
<fu:TaxNumber>99999862</fu:TaxNumber>
<fu:BusinessPremiseID>P001</fu:BusinessPremiseID>
<fu:BPIdentifier>
<fu:RealEstateBP>
<fu:PropertyID>
<fu:CadastralNumber>2606</fu:CadastralNumber>
<fu:BuildingNumber>6967</fu:BuildingNumber>
<fu:BuildingSectionNumber>1</fu:BuildingSectionNumber>
</fu:PropertyID>
<fu:Address>
<fu:Street>TEST</fu:Street>
<fu:HouseNumber>7</fu:HouseNumber>
<fu:HouseNumberAdditional>C</fu:HouseNumberAdditional>
<fu:Community>KOPER</fu:Community>
<fu:City>KOPER</fu:City>
<fu:PostalCode>6000</fu:PostalCode>
</fu:Address>
</fu:RealEstateBP>
</fu:BPIdentifier>
<fu:ValidityDate>2010-09-24</fu:ValidityDate>
<fu:SoftwareSupplier>
<fu:TaxNumber>10031685</fu:TaxNumber>
</fu:SoftwareSupplier>
<fu:SpecialNotes>Primer prijave poslovnega prostora</fu:SpecialNotes>
</fu:BusinessPremise>
</fu:BusinessPremiseRequest>
</soapenv:Body>

现在我想在 Java 中使用我的私钥对 xml 进行签名。

XPathFactory factory = XPathFactory.newInstance();
List transforms = null;

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

Reference ref = fac.newReference(
"#data",
fac.newDigestMethod(DigestMethod.SHA256, null),
transforms,
null,
null
);

SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null),
Collections.singletonList(ref));

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);

Document doc = (Document) dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));


KeyStore p12 = KeyStore.getInstance("pkcs12");
p12.load(new FileInputStream("c:/cert/furspeter.pfx"), "PWD".toCharArray());


Enumeration e = p12.aliases();
String alias = (String) e.nextElement();
System.out.println("Alias certifikata:" + alias);
Key privateKey = p12.getKey(alias, "PWD".toCharArray());

KeyStore.PrivateKeyEntry keyEntry
= (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection("PWD".toCharArray()));

X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

KeyInfoFactory kif = fac.getKeyInfoFactory();

System.out.println(cert.getSerialNumber());

X509IssuerSerial x509IssuerSerial = kif.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());

List x509Content = new ArrayList();
System.out.println("ime: " + cert.getSubjectX500Principal().getName());
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(x509IssuerSerial);

X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc);

OutputStream os = new FileOutputStream("c:/SignedXml.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));

我想要的是在“fu:BusinessPremiseRequst”节点中获取“Signature”节点。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:fu="http://www.fu.gov.si/" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">
<soapenv:Body>
<fu:BusinessPremiseRequest Id="data">
<fu:Header>...</fu:Header>
<fu:BusinessPremise>...</fu:BusinessPremise>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</fu:BusinessPremiseRequest>
</soapenv:Body>

在我的例子中,我把节点放在了错误的位置(下面的例子)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fu="http://www.fu.gov.si/" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">
<soapenv:Body>
<fu:BusinessPremiseRequest Id="data">
....
</fu:BusinessPremiseRequest>
</soapenv:Body>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">..</Signature>
</soapenv:Envelope>

我在 Java 示例中做错了什么?或者如何在内部移动节点?

最佳答案

你的错误可能在这里:DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement());您告诉 DOMSignContext Signature 应该附加到主文档元素。

如果你想在 fu:BusinessPremiseRequest 中使用它,你应该首先获取该节点,并将其作为参数传递给 new DOMSignContext() 构造函数。

关于java - 如何在 Java 中移动签名 XML 中的签名节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32840123/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com