【问题标题】:Signature Reference can not be resolved (Apache Santuario)无法解析签名引用(Apache Santuario)
【发布时间】:2017-06-29 12:23:19
【问题描述】:

我想通过使用 apache santuario lib 创建一个 xml 签名,并通过引用该元素将自定义元素包含到签名计算中。这是我到目前为止得到的,并且工作正常:

public void signXmlNode(Node n) {
    try {
        Reference qSigRef = sigFactory.newReference(
                "#SignatureProperties", sigFactory.newDigestMethod(
                        this.refAlgo, null), Collections
                        .singletonList(sigFactory.newTransform(
                                CanonicalizationMethod.EXCLUSIVE,
                                (TransformParameterSpec) null)),
                "http://uri.etsi.org/01903#SignedProperties",
                "Reference-SignedProperties-1497606229690");

        SignedInfo signedInfo = sigFactory.newSignedInfo(sigFactory
                .newCanonicalizationMethod(
                        CanonicalizationMethod.EXCLUSIVE,
                        (C14NMethodParameterSpec) null), sigFactory
                .newSignatureMethod(this.sigAlgo, null), Arrays.asList(
                qSigRef));
        Element qSig = createXades(n.getOwnerDocument());
        XMLObject xmlObject = sigFactory.newXMLObject(
                Collections.singletonList(new DOMStructure(qSig)),
                "SignatureProperties", null, null);

        KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
        List<Object> x509Content = new ArrayList<>();
        x509Content.add(signerCert);
        X509Data xd = keyInfoFactory.newX509Data(x509Content);
        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections
                .singletonList(xd));

        XMLSignature xmlSignature = sigFactory.newXMLSignature(signedInfo,
                keyInfo, Collections.singletonList(xmlObject), "Signature-"
                        + SIGNATURE_ID, null);
        DOMSignContext signContext = new DOMSignContext(signerKey, n);
        signContext.setDefaultNamespacePrefix("ds");
        xmlSignature.sign(signContext);
        final Transformer t = TransformerFactory.newInstance()
                .newTransformer();
        t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        t.setOutputProperty(OutputKeys.INDENT, "yes");
        final StringWriter w = new StringWriter();
        t.transform(new DOMSource(n), new StreamResult(w));
        System.out.println(w.toString());
    } catch (MarshalException ex) {
        log.log(Level.WARNING, "MarshalException in handler!", ex);
    } catch (XMLSignatureException ex) {
        log.log(Level.WARNING, "XMLSignatureException in handler!", ex);
    } catch (InvalidAlgorithmParameterException ex) {
        log.log(Level.SEVERE, "InvalidAlgorithmParameterException "
                + "while signing message!", ex);
        logSecurityProviders();
    } catch (NoSuchAlgorithmException ex) {
        log.log(Level.SEVERE, "NoSuchAlgorithmException "
                + "while signing message!", ex);
        logSecurityProviders();
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerFactoryConfigurationError e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    }
}

private Element createXades(Document doc) {
    Element qualifyingProperties = doc.createElementNS(
            "http://uri.etsi.org/01903/v1.3.2#",
            "xades:QualifyingProperties");
    qualifyingProperties.setAttribute("Target", "#Signature-"
            + SIGNATURE_ID);
    Element signedProperties = qualifyingProperties.getOwnerDocument()
            .createElementNS("http://uri.etsi.org/01903/v1.3.2#",
                    "xades:SignedProperties");
    signedProperties.setAttribute("Id", "SignedProperties-" + SIGNATURE_ID);
    Element signedSignatureProperties = signedProperties.getOwnerDocument()
            .createElementNS("http://uri.etsi.org/01903/v1.3.2#",
                    "xades:SignedSignatureProperties");


    signedProperties.appendChild(signedSignatureProperties);
    qualifyingProperties.appendChild(signedProperties);
    return qualifyingProperties;
}

现在,我希望引用 qSigRef 引用 xml 元素 &lt;xades:SignedProperties Id="SignedProperties-0123456789"&gt; 而不是 &lt;Object ID="SignatureProperties"&gt;。将 URI 从“#SignatureProperties”更改为“SignedProperties-0123456789”后(如下所示):

Reference qSigRef = sigFactory.newReference(
                "#SignatureProperties", sigFactory.newDigestMethod(
                        this.refAlgo, null), Collections
                        .singletonList(sigFactory.newTransform(
                                CanonicalizationMethod.EXCLUSIVE,
                                (TransformParameterSpec) null)),
                "http://uri.etsi.org/01903#SignedProperties",
                "Reference-SignedProperties-1497606229690");

Reference qSigRef = sigFactory.newReference(
                "#SignedProperties-0123456789", sigFactory.newDigestMethod(
                        this.refAlgo, null), Collections
                        .singletonList(sigFactory.newTransform(
                                CanonicalizationMethod.EXCLUSIVE,
                                (TransformParameterSpec) null)),
                "http://uri.etsi.org/01903#SignedProperties",
                "Reference-SignedProperties-1497606229690");

抛出一个 XMLSignatureException 声明:

javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: org.apache.xml.security.utils.resolver.ResourceResolverException:  Cannot resolve element with ID SignedProperties-0123456789

由于我找不到任何解决方案,也找不到抛出异常的原因,所以我决定在这里问这个问题。

【问题讨论】:

    标签: java apache xml-signature


    【解决方案1】:

    我解决了这个问题。

    我必须注册 SignedProperties 元素的 id 属性。

    这是通过调用相关元素的 setIdAttributeNS() 来隐式存档的:

    Element signedProperties = qualifyingProperties.getOwnerDocument()
                    .createElementNS("http://uri.etsi.org/01903/v1.3.2#",
                            "xades:SignedProperties");
            signedProperties.setAttributeNS("", "Id", "SignedProperties-"
                    + SIGNATURE_ID);//Set ID attribute
    
            signedProperties.setIdAttributeNS("", "Id", true);//register attribute as id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多