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

天大地大妈咪最大 提交于 2020-01-12 21:48:12

问题


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>

回答1:


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));



回答2:


String algoritmo = XMLSignature.ALGO_ID_SIGNATURE_RSA; XMLSignature sig = new XMLSignature(doc, algoritmo);




回答3:


If you want to have your signed XML in below format

<ds:Signature ...> ... </ds:Signature>

Then kindly use java 6 version 31 and you will the required signed XML.



来源:https://stackoverflow.com/questions/16300486/how-to-add-namespace-while-signing-xml-file-using-javax-xml-crypto-dsig

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!