Skip to Content
Technical Articles
Author's profile photo Fariha Kazi

Nation wants to know : SAP PI – XML digital signatures and its usage for Non-repudiation

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 !!

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.