简体   繁体   中英

How can I digitally sign an XML document fragment in Java

Please refer to the xml below. I have been asked to digitally sign the document fragment denoted by:

<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="XYZAssertion" IssueInstant="2014-12-09T18:56:16.636Z" Version="2.0">

When this is completed, the tag currently noted below:

<Reference URI="">

should become:

<Reference URI="#XYZAssertion">

I am using Apache Santuario and have found many examples to sign the xml document in its entirety but none for the fragment and to set the Reference URI using Java. Given this environment, how do I sign the fragment?

Here the base code for signing the document in its entirety:

// Instantiate the document to be signed
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(fileNameIn));
DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(si, ki);

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

XML:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="XYZResponse" IssueInstant="2014-12-26T11:40:12.901-06:00" Version="2.0">
   <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">ComEdRRTPAssertion</saml:Issuer>
   <samlp:Status>
      <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
   </samlp:Status>
   <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="XYZAssertion" IssueInstant="2014-12-09T18:56:16.636Z" Version="2.0">
      <saml:Issuer>ComEdRRTP</saml:Issuer>
      <saml:Subject>
         <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">user's RRTPID</saml:NameID>
         <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml:SubjectConfirmationData NotOnOrAfter="2014-12-26T17:40:12.901-06:00" Recipient="https://test.amplifinity.net/ee/sso/HandleSamlLoginResponse" />
         </saml:SubjectConfirmation>
      </saml:Subject>
      <saml:Conditions NotBefore="2014-12-26T11:40:12.901-06:00" NotOnOrAfter="2014-12-26T17:40:12.901-06:00">
         <saml:AudienceRestriction>
            <saml:Audience>sso:sp:amplifinity</saml:Audience>
         </saml:AudienceRestriction>
      </saml:Conditions>
      <saml:AuthnStatement AuthnInstant="2014-12-26T11:40:12.901-06:00" SessionIndex="1">
         <saml:AuthnContext>
            <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
         </saml:AuthnContext>
      </saml:AuthnStatement>
      <saml:AttributeStatement>
      </saml:AttributeStatement>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
         <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-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>Xq7+w0EUWGyM1dsJqKsIlV1hPO0=</DigestValue>
            </Reference>
         </SignedInfo>
         <SignatureValue>VNPKl2vfj62PLCgcDxvGHL1R8noreaeOuHK0cKcTOOsNJ2SZ9q9n9A==</SignatureValue>
         <KeyInfo>
            <KeyValue>
               <DSAKeyValue>
                  <P>...</P>
                  <Q>...</Q>
                  <G>.../G>
                  <Y>...</Y>
               </DSAKeyValue>
            </KeyValue>
         </KeyInfo>
      </Signature>
   </saml:Assertion>
</samlp:Response>

The DOMSignContext takes an XML element and its children then the XMLSignature signs it. So instead of using doc.getDocumentElement() you would just replace it with an XML element of your choice. That element and its children will be signed.

Note that I haven't personally used the API, but that's what the documentation indicates. Have you tried it?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM