微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何仅对 XML 文件的一部分进行签名 - Java XMLSignature - 但出现错误

如何解决如何仅对 XML 文件的一部分进行签名 - Java XMLSignature - 但出现错误

我只是想对 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?