问题描述
我只是想对 XML 的一部分进行数字签名。
要签名的 XML 是这样的:
<Invoice>
<DataInvoice Id="data">
----
</DataInvoice>
<DataSignature>
<SignatureSeller Id="seller">
</SignatureSeller>
</DataInvoice>
</Invoice>
签名后的xml
<Invoice>
<DataInvoice Id="data">
----
</DataInvoice>
<DataSignature>
<SignatureSeller Id="seller">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="data">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>49uyshWL+fnQ2UetAe2t3BNQqnA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
VWI03lBKlE/wVT//uHME4qLyUs2PqxOgq0KBYaGYcR6z3QZdnXqOZClu9EVMT2V3RBA7hr+QQy2cCHVsdtb85B2gsNsRdxHPjj9KfLetTFx1lL8nlC6L5SA0x6k9Lh7xNBZTJl275IT4hnSnNe8q+9dWskgE/6We24DKBLMrOLg=
</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
MIIEDzCCAvegAwIBAgIQVAT//rcDP7MW1nIgG4H6OjANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJWTjESMBAGA1UEBwwJSmogIE7hu5lpMRYwFAYDVQQKEw1WaWV0dGVsIEdyb3VwMRMwEQYDVQQDEwpWaWV0dGVsLUNBMB4XDTIwMDYwODA5NDMyNFoXDtixMDYwODA5NDMyNFowgYoxITAfBgkqhkiG9w0BCQEWEmh1b25nbnRAbWF0YmFvLmNvbTEeMBwGCgmSJomT8ixkAQEMDk1TVDowMzAyNzEyNTcxmsgwJgYDVQQDDB9Dw5RORyBUWSBD4buUIFBI4bqmTiBN4bquVCBCw4NPMQ4wDAYDVQQHDAVUUEhDTTELMAkGA1UEBhMCVk4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJQ3aZioAdDIU1rQOO5tN7ORCqAWDWkQvP24gqD8LzRhA1Ui27DcOukuTp2bG8zSB3vGUMoFxV8qOpkfpt4/YUFhrMR6fG3k7J4YAKhkI/Ear3m3cEHo/MKxKsMbWHriI2CrKbG7Ih51iafRyt/mlgi66fNfnIwAoSIeXvLXi5YDAgMBAAGjggEuMIIBKjA1BggrBgEFBQcBAQQpMccwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnZpZXR0ZWwtY2Eudm4wHQYDVR0OBBYEFHQbrRodIeEnE0sMBLuNyp+lCsvhMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU/stBFOldp9kyDeSyCFzxXOy2srUwgZIGA1UdHwSBijCBhzCBhKAuoCyGKmh0dHA6Ly9jcmwudmlldHRlbC1jYS52bi9WaWV0dGVsLUNBLXYzLmNybKJSpFAwTjETMBEGA1UEAwwKVmlldHRlbC1DQTEWMBQGA1UECgwNVmlldHRlbCBHcm91cDESMBAGA1UEBwwJSmogIE7hu5lpMQswCQYDVQQGEwJWTjAOBgNVHQ8BAf8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggEBAJInz1BLmnJIfl8juAs+StPAl4a5bd9Gf4B6eksmYOBFLeUzc/B78LcO9B2z3fpOVcqOvsK9rCFMO81+TePa6KZODk4xnP2HjgpuiN+E/qdYucUSMQNNVH2BDa/BraK41H1ySVVuqxvQ5fAvkIfhgBuyt3RVRmBpWkRT1faJ1hh5o9sq3SBqTmqd+W5PmA4hOUHj/Rb4xcQF3hMywWIBnVXZAwJ+GTbF4T/XkFavxb54UObTuebaQ8deB4hIOMvM6SKagFofBVeurS7CELMQtHKBjVRndlzecK0zR6vzKDLBukL6W4K7s9u55A2563Vv5HhZJhQHnftlrmJ59bBUHx0=
</X509Certificate>
</X509Data>
</KeyInfo>
<Object xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignatureProperties>
<SignatureProperty>
<SigningTime>2021-05-27T14:13:48</SigningTime>
</SignatureProperty>
</SignatureProperties>
</Object>
</Signature>
</SignatureSeller>
</DataInvoice>
</Invoice>
这是我用来尝试对其进行签名的代码,但我只需要对 XML 的一部分进行签名并将结果放入此 Id 中
public String xmlSign(String xml,String idData,String signBy) throws
NoSuchAlgorithmException,InvalidAlgorithmParameterException,InterruptedException,UnrecoverableKeyException,KeyStoreException,SAXException,IOException,ParserConfigurationException,XPathExpressionException,MarshalException,XMLSignatureException
{
PublicKey publicKey = null;
PrivateKey privateKey = null;
if (!(cert instanceof Certificate)) {
Map<String,Certificate> aliases = store.getAliases();
for (Map.Entry<String,Certificate> item : aliases.entrySet()) {
Certificate tmpCert = item.getValue();
publicKey = tmpCert.getCertificate().getPublicKey();
privateKey = (PrivateKey) store.getKeyStore().getKey(tmpCert.getAlias(),null);
if (publicKey instanceof PublicKey && privateKey instanceof PrivateKey) {
cert = tmpCert;
break;
}
}
} else {
publicKey = cert.getCertificate().getPublicKey();
privateKey = (PrivateKey) store.getKeyStore().getKey(cert.getAlias(),null);
}
if (publicKey == null || privateKey == null) {
return null;
}
// Load factory
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
// Load xml document
Document document = this.importXML(this.ignoreLineBreak(xml));
XMLObject xmlObject = factory.newXMLObject(Collections.singletonList(new DOMStructure(createTimestamp(document))),null,null);
XPathExpression exprAssertion = xpath.compile(String.format("//*[@Id='%s']",idData));
Element assertionNode = (Element) exprAssertion.evaluate(document,XPathConstants.NODE);
assertionNode.setIdAttribute("Id",true);
// Retreive Subject Node because the signature will be inserted before.
XPathExpression exprAssertionSubject = xpath.compile(String.format("//*[@Id='%s']","seller"));
Node insertionNode = (Node) exprAssertionSubject.evaluate(document,XPathConstants.NODE);
DOMSignContext signContext = new DOMSignContext(privateKey,assertionNode,insertionNode);
// Create transform
List<Transform> transformlist = new ArrayList<Transform>();
Transform exc14nTranform = ((XMLSignatureFactory) factory).newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315",(TransformParameterSpec) null);
Transform envTransform = ((XMLSignatureFactory) factory).newTransform(Transform.ENVELOPED,(TransformParameterSpec) null);
transformlist.add(exc14nTranform);
transformlist.add(envTransform);
// Create reference
DigestMethod digestMethod = factory.newDigestMethod(DigestMethod.SHA1,null);
Reference reference = factory.newReference("#" + idData,digestMethod,transformlist,(signBy != null ? "#" + signBy : null));
// Create key info
KeyInfoFactory kif = ((XMLSignatureFactory) factory).getKeyInfoFactory();
List<X509Certificate> x509Content = new ArrayList<X509Certificate>();
x509Content.add(cert.getCertificate());
X509Data xd = kif.newX509Data(x509Content);
KeyInfo keyInfo = kif.newKeyInfo(Collections.singletonList(xd));
// Create signature info
SignedInfo signInfo = ((XMLSignatureFactory) factory).newSignedInfo(
((XMLSignatureFactory) factory).newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,(C14NMethodParameterSpec) null
),((XMLSignatureFactory) factory).newSignatureMethod(
SignatureMethod.RSA_SHA1,null
),Collections.singletonList(reference)
);
XMLSignature signature = factory.newXMLSignature(signInfo,keyInfo,Collections.singletonList(xmlObject),null);
signature.sign(signContext);
return this.ignoreLineBreak(
this.exportXML(new DOMSource(document))
);
}
NOT_FOUND_ERR:尝试在不存在的上下文中引用节点。 com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore(来源不明)
任何帮助将不胜感激。 问候
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)