Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add namespace while signing XML file using javax.xml.crypto.dsig.*?

I'm trying to sign an xml file using enveloped signature and javax.xml.crypto.dsig.* classes. As a result I get file with correct Signature content but with no namespace defined. How can I add xmlns:ds="http://www.w3.org/2000/09/xmldsig#" namespace and corresponding ds prefixes? I don't see any place where I could define it.

Example code:

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

    (...)

    XMLSignature signature = xmlSignatureFactory.newXMLSignature(signedInfo, keyInfo);

    // Marshal, generate, and sign the enveloped signature.
    signature.sign(domSignContext);

gives example XML:

<?xml version="1.0" encoding="UTF-8"?>
<test xmlns="http://different.namespace.com">
    <someBody/>
    <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="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <DigestValue>base64_digest</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>some_base64</SignatureValue>
        <KeyInfo>
            <X509Data> 
                <X509SubjectName>subject_data</X509SubjectName>
                <X509Certificate>some_more_base64</X509Certificate>
            </X509Data>
            <KeyValue>
                <RSAKeyValue>
                    <Modulus>another_base64</Modulus>
                    <Exponent>base64_as_well</Exponent>
                </RSAKeyValue>
            </KeyValue>
        </KeyInfo>
   </Signature>
</test>

but I want:

<?xml version="1.0" encoding="UTF-8"?>
<test xmlns="http://different.namespace.com" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <someBody/>
    <ds:Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>     
            <ds:Reference URI="">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <ds:DigestValue>base64_digest</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>some_base64</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data> 
                <ds:X509SubjectName>subject_data</ds:X509SubjectName>
                <ds:X509Certificate>some_more_base64</ds:X509Certificate>
            </ds:X509Data>
            <ds:KeyValue>
                <ds:RSAKeyValue>
                    <ds:Modulus>another_base64</ds:Modulus>
                    <ds:Exponent>base64_as_well</ds:Exponent>
                </ds:RSAKeyValue>
            </ds:KeyValue>
        </ds:KeyInfo>
   </ds:Signature>
</test>
like image 503
jasiustasiu Avatar asked Apr 30 '13 12:04

jasiustasiu


People also ask

What is the use of namespace in XML?

XML namespaces associate element and attribute names in an XML document with custom and predefined URIs. To create these associations, you define prefixes for namespace URIs, and use those prefixes to qualify element and attribute names in XML data.

Does xmlnamespacemanager support XPath?

For example, the XsltContext class uses XmlNamespaceManager for XPath support. The namespace manager doesn't perform any validation on the namespaces, but assumes that prefixes and namespaces have already been verified and conform to the W3C Namespaces specification.

What is the Java XML Digital Signature API?

One of the significant new features of the Java Platform, Standard Edition 6 (Java SE 6) is the Java XML Digital Signature API. This API allows you to generate and validate XML signatures.

What is a namespace element in Spring Security?

XML Namespace configuration has been available since Spring Security 2.0. In Spring Framework, A namespace element is nothing but it is a more concise way of configuring an individual bean or, more powerfully, to define an alternative configuration syntax.


1 Answers

Below is the sample code from Oracle for generating enveloped signature. And i guess what you are looking for is dsc.setDefaultNamespacePrefix("dsig"); as shown in the example below.

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

    Reference ref = fac.newReference
    ("", fac.newDigestMethod(DigestMethod.SHA1, null),
            Collections.singletonList
            (fac.newTransform
                    (Transform.ENVELOPED, (TransformParameterSpec) null)),
                    null, null);

    // Create the SignedInfo
    SignedInfo si = fac.newSignedInfo
    (fac.newCanonicalizationMethod
            (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                    (C14NMethodParameterSpec) null),
                    fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
                    Collections.singletonList(ref));

    // Create a DSA KeyPair
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
    kpg.initialize(512);
    KeyPair kp = kpg.generateKeyPair();

    // Create a KeyValue containing the DSA PublicKey that was generated
    KeyInfoFactory kif = fac.getKeyInfoFactory();
    KeyValue kv = kif.newKeyValue(kp.getPublic());

    // Create a KeyInfo and add the KeyValue to it
    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

    // Instantiate the document to be signed
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =  dbf.newDocumentBuilder().parse(new FileInputStream(sourceFile));

    // Create a DOMSignContext and specify the DSA PrivateKey and
    // location of the resulting XMLSignature's parent element
    DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement());
    dsc.setDefaultNamespacePrefix("dsig");

    // Create the XMLSignature (but don't sign it yet)
    XMLSignature signature = fac.newXMLSignature(si, ki);

    // Marshal, generate (and sign) the enveloped signature
    signature.sign(dsc);

    // output the resulting document
    OutputStream os;
    os = new FileOutputStream(DestinationFile);

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer trans = tf.newTransformer();
    trans.transform(new DOMSource(doc), new StreamResult(os));
like image 73
user2795124 Avatar answered Oct 21 '22 19:10

user2795124