Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member190389
Active Contributor
Like non-XML digital signatures, XML signatures add

  • Authentication

  • Data integrity

  • and support for non-repudiation to the data that is object of XML digital signing process.


A fundamental feature of XML Signature is the ability to sign only specific portions of the XML content rather than the complete document.

This is helpful when a single XML document may have a long history of parts which are authored at different times by different parties, each signing only those elements relevant to it.

This flexibility will also be critical in situations where it is important to ensure the integrity of certain portions of an XML document, while leaving open the possibility for other portions of the document to change.

In this blog , however, we are going to cover how we achieve a java mapping that does this job and signs the whole document.

We take for an example a HMAC key type with  SHA1 digest hash method which uses a secret key that you share with your other partner to verify the xml.

Other possible example could be using certificate based digital signature.

We also sign the whole document rather than a part for this example.

The signature canonicalization that we use is Canonical xml without comments to get uniformity i.e.
http://www.w3.org/TR/2001/REC-xml-c14n-20010315

Libraries used :




  • Apache commons-io-2.4

  • Apache xml sec 2.0.9



 

So here we sign this xml :
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<AppendHere id="here">
</AppendHere>
<Comments>The price is $30</Comments>
</Root>

 

into this
<?xml version="1.0" encoding="UTF-8"?><Root>
<AppendHere id="here">
<ds:Signature xmlns:ds="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#hmac-sha1"/>
<ds:Reference URI="#xpointer(/)">
<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>Q4KJ3D+IGMUVeNj/OA10MWlNBgA=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>xwZLw4/qSMGyht8/SALD40tmP+s=</ds:SignatureValue>
</ds:Signature></AppendHere>
<Comments>The price is $30</Comments>
</Root>

 

Instantiate and set the DOM factory
DocumentBuilderFactory  factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
factory.setValidating(false);
factory.setIgnoringElementContentWhitespace(false);

 

Parse the XML from Java mapping input stream

 
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(inStream);
is.setEncoding("UTF-8");
Document document = builder.parse(is);

 

Canonicalize the xml to get uniformity
org.apache.xml.security.Init.init();
Canonicalizer c14n = Canonicalizer.getInstance("http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
byte outputBytes[] = c14n.canonicalizeSubtree(document);
document= builder.parse(new ByteArrayInputStream(outputBytes));

 

Set the password ( password is set as an input parameter to the parameterised java mapping so that we can switch easily )
final Charset charSet = Charset.forName("ASCII");
final SecretKeySpec signingKey = new javax.crypto.spec.SecretKeySpec(charSet.encode(password).array(), "HmacSHA1");

 

Create an xml Signature element
org.apache.xml.security.signature.XMLSignature sig = new org.apache.xml.security.signature.XMLSignature(document,"",org.apache.xml.security.signature.XMLSignature.ALGO_ID_MAC_HMAC_SHA1);
document.getElementsByTagName("AppendHere").item(0).appendChild(sig.getElement());

 

Specify the Transforms :

You can add the signature inside the xml payload or envelope the whole payload.

Here we use enveloped method.
Transforms transforms = new Transforms(document);
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);

 

Various types of transforms are listed below :


 

Tell what part to sign with the secret key password that you share with your other partner and with which algorithm (here we use whole document '#xpointer (/) ')
sig.addDocument("#xpointer(/)", transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
sig.sign(signingKey);

 

The generated xml will have all the elements and  algorithms used as below , and it will be added to the node that you specify (here <AppendHere>)

The Signature Value is calculated based on SignedInfo generated:
<AppendHere>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"></ds:SignatureMethod>
<ds:Reference URI="#xpointer(/)">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>LB/n8Ir8iJlrMyJkL1Ue5TWhJwk=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>inmGAJ4Wzej+Ir/f835EIeMAPgk=</ds:SignatureValue>
</ds:Signature>
</AppendHere>

 

So here we have it The leaked information !!
Labels in this area