XML Security with Digital Signature in JAVA
Introduction
As you know XML plays a major role in our product or project development and from an XML document we gather lot of information and also we can perform CRUD operations with XML files. But it is a matter of concern as to how we can ensure that the data available in an XML file are authentic and data came from a trusted and a reliable source. There may be many questions about the authenticity or originality of the data from an XML file. It is a common practice on the part of a developer to process an XML document without considering the authenticity of the data. But there are situations where address all the points and questions made in the above lines. Let us consider a real world situation, whenever we get a letter or mail from our post office, how do we know that the letter has come from our friend/s ? It is based upon his/her typical statements or words or address details. It may be his/her character signature. Now-a-days it is also possible the letter we have received has been modified by an unknown person by adding an another page. For all that reasons we normally verify the handwriting signature of our friend. This is all about the normal post office letter. What about an electronic message? How can we verify that the electronic message is authentic? In this case we have to adopt the technology for digital signature. In this article I will present a brief glimpse XML Digital Signature which plays a significant role for our data integrity. In this article I will show you how to attach a digital signature to an XML document and how to verify the XML document with the attached signature.
Technicalities
In the last couple of years XML Digital Signature has gained momentum particularly in the field of financial sector. Before we jump into XML Digital signature, let us consider a typical scenario for our understanding. Think about a situation where an organization sends all the salary details of its employees to the Income Tax department in the form of XML document. Now it is a question how does Income Tax department verify the XML document? It means IT department has to verify the sensitive information of all the employees of an organization. IT department has to ensure that the XML document has come from trusted source and the document has not yet been modified while coming to the IT department. It means the document has not been tempered in between. First of all we have to understand the concept of digital signature. Digital signature is an electronic signature that is used to validate the authenticity of the document sent by a trusted person. It also provides assurance that the original content of the document has not been modified during transmission. A digital signature can be used with any message, whether it is encrypted or not, so that the receiver can be sure of the identity of the sender and that the message has not been altered by an unknown person. According to Wikipedia , A digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document. A valid digital signature gives a recipient reason to believe that the message was created by a known sender, such that the sender cannot deny having sent the message (authentication and non-repudiation) and that the message was not altered in transit (integrity). Digital signatures are commonly used for software distribution, financial transactions, and in other cases where it is important to detect forgery or tampering.
Let us see a complete XML document with a digital signature.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><SalaryDeposit> <Organisation> <Name>DDLab Inc</Name> <AccountNo>SBC-12345789</AccountNo> </Organisation> <Employees> <Emp> <Name>John Abraham</Name> <AccountNo>SB-001</AccountNo> <Amount>1234</Amount> </Emp> <Emp> <Name>Bipasha Basu</Name> <AccountNo>SB-002</AccountNo> <Amount>2334</Amount> </Emp> <Emp> <Name>Vidya Balan</Name> <AccountNo>SB-003</AccountNo> <Amount>3465</Amount> </Emp> <Emp> <Name>Debadatta Mishra</Name> <AccountNo>SB-007</AccountNo> <Amount>5789</Amount> </Emp> <Emp> <Name>Priti Zinta</Name> <AccountNo>SB-009</AccountNo> <Amount>1234</Amount> </Emp> </Employees> <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>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue> </Reference> </SignedInfo> <SignatureValue> aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6l e8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f 2/ofHujYZ01D6+YqI8c= </SignatureValue> <KeyInfo> <KeyValue> <RSAKeyValue> <Modulus> jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl 6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvf gbvcRPgxDZZqfIzDmDU=</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> </Signature> </SalaryDeposit>
The above XML file is a digitally signed one which can be verified at any point of time. The above XML file contains information about the employee name, account number and salary amount. But the actual digital signature is attached within the tag <Signature></Signature>. The information lying inside <Signature> provides the authenticity of the document. As you are able to see the data, you can freely change the data, but it will fail in case signature verification process.
Basically there are three types of XML signatures.
- Enveloped Signature
- Enveloping Signature
- Detached Signatures
Enveloped Signature
In this case, signature is the child of the XML object which is signed. It means <Signature> is a child XML tag in the mail XML document. The following is the structure of the enveloped digital signature.
<RootElement> <Signature> …………………… </Signature> </ RootElement>
In this article I will present you how to create an enveloped XML digital signature.
Enveloping Signature
In this case XML document remains inside the Signature object. It means <Signature> tag becomes the root element of the signed XML document. The following is the outline of the enveloping digital signature.
<Signature > < MyXMLDocument > … </ MyXMLDocument > </Signature>
Detached Signature
In this case, the digital signature is generated independently and it is not part of the XML document. It means you will have two XML files, one is your XML file to be signed and another is the XML signature. Let see the skeletal structure of the XML document.
<Signature> ………….. </Signature>
Now let us see the skeletal structure of a typical XML digital signature below.
<Signature xmlns=""> <SignedInfo> <CanonicalizationMethod Algorithm="" /> <SignatureMethod Algorithm="" /> <Reference URI=""> <Transforms> <Transform Algorithm="" /> </Transforms> <DigestMethod Algorithm="" /> <DigestValue></DigestValue> </Reference> </SignedInfo> <SignatureValue></SignatureValue> <KeyInfo> <KeyValue> <RSAKeyValue> <Modulus></Modulus> <Exponent></Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> </Signature>
The XML tag <Signature> basically contains 3 children tags. It can be viewed as
<Signature> <SignedInfo></SignedInfo> <SignatureValue></SignatureValue> <KeyInfo></KeyInfo> </Signature>
Here <Signature> is the root element of the XML digital signature concept and it is a protocol that must be followed as instructed by W3C. <SignedInfo> element is the information that you signed. <SignatureValue> contains the actual signature with Base64-encoded content and finally <KeyInfo> indicates the public key. Again let us look into the <SignedInfo> tag. The structure of <SignedInfo> is given below.
<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>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue> </Reference> </SignedInfo>
While creating XML digital signature in java , SignedInfo object is used to create an element inside the Signature tag of the digital signature. This is also part of the XML digital signature protocol as suggested by W3C.
Now let us look into the XML tag <KeyInfo> structure below.
<KeyInfo> <KeyValue> <RSAKeyValue> <Modulus></Modulus> <Exponent></Exponent> </RSAKeyValue> </KeyValue> </KeyInfo>
<KeyInfo> tag contains the information which is calculated mathematically and basically it caontains modulus and exponent of the Public Key.
In order to create an XML digital signature, follow the following steps.
- Generate a pair of Keys called Private Key and Pubic Key.
- Obtain the original XML document.
- Sign the original XML document using both Private and Public key by Java API and generate another document which has XML digital signature.
Let us see brief java code snippet for generating XML digital signature.
public void generateXMLDigitalSignature(String originalXmlFilePath, String destnSignedXmlFilePath, String privateKeyFilePath, String publicKeyFilePath) { //Get the XML Document object Document doc = getXmlDocument(originalXmlFilePath); //Create XML Signature Factory XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM"); PrivateKey privateKey = new KryptoUtil().getStoredPrivateKey(privateKeyFilePath); DOMSignContext domSignCtx = new DOMSignContext(privateKey, doc.getDocumentElement()); Reference ref = null; SignedInfo signedInfo = null; try { ref = xmlSigFactory.newReference("", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); signedInfo = xmlSigFactory.newSignedInfo( xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (InvalidAlgorithmParameterException ex) { ex.printStackTrace(); } //Pass the Public Key File Path KeyInfo keyInfo = getKeyInfo(xmlSigFactory, publicKeyFilePath); //Create a new XML Signature XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo); try { //Sign the document xmlSignature.sign(domSignCtx); } catch (MarshalException ex) { ex.printStackTrace(); } catch (XMLSignatureException ex) { ex.printStackTrace(); } //Store the digitally signed document inta a location storeSignedDoc(doc, destnSignedXmlFilePath); }
XML Signature Verification
The XML digital signature verification involves the following operations.
- Verify the digital signature
- Calculate the digest of the <SignedInfo> element
- Unsign the <SignatureValue> element with public key
- Compare the above two values
- Computing the digests of the references
- Recalculate the digests of the references in the <SignedInfo> element
- Compare them with the digest values specified in <DigestValue>
In order to verify a signed XML document, follow the following steps.
- Obtain both signed XML document and Public key.
- Verifying the digital signature of the <SignedInfo> element
- Calculate the digest of the <SignedInfo> element and compare the values.
Let us see the brief java code snippet of XML digital signature verification.
public static boolean isXmlDigitalSignatureValid(String signedXmlFilePath, String pubicKeyFilePath) throws Exception { boolean validFlag = false; Document doc = getXmlDocument(signedXmlFilePath); NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nl.getLength() == 0) { throw new Exception("No XML Digital Signature Found, document is discarded"); } PublicKey publicKey = new KryptoUtil().getStoredPublicKey(pubicKeyFilePath); DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0)); XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); XMLSignature signature = fac.unmarshalXMLSignature(valContext); validFlag = signature.validate(valContext); return validFlag; }
So from the above code, it is clear that an XML signature can be verified by recalculating the digest value of the <SignedInfo> element using the digest algorithm specified in the <SignatureMethod> element, and by using the public key to verify that the value of the <SignatureValue> element is correct for the digest value of the <SignedInfo> element. The digest of the references is recalculated within the <SignedInfo> element and compare them to the digest values contained in each <Reference> element’s corresponding <DigestValue> element. Still let us get familiar with some of the java components responsible for XML digital signature.
XMLSignatureFactory
It is a factory object for generating digital signature for an XML document using “DOM” mechanism type. The object is created in the following manner.
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
DOMSignContext
DOMSignContext object is used to form the DOM tree where an XML digital signature will be attached while creating a digital signature. This object accepts the private key and the root element of the XML document.
Reference
Reference object is used to create as an element inside SignedInfo element of main Signature tag for the XML digital signature. This object creates a tag as a part of rule for W3C XML-Signature Syntax and Processing. The basic structure of Reference element is given below.
<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>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue> </Reference>
SignedInfo
Similarly SignedInfo object is used to create an element inside the Signature tag of the digital signature. This is also part of the XML digital signature protocol as suggested by W3C.
The basic structure is given below.
<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>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue> </Reference> </SignedInfo>
XMLSignature
Finally XMLSignature object is created to form the signature tag which is used as an envelope attached to an XML document. As per W3C guide lines, this is root element of the XML digital signature.
The complete structure is given below.
<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>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue> </Reference> </SignedInfo> <SignatureValue>aUEMrCT5dzeOfSNaznzoT0If8WZ8KQcMNXDqtoeseonVk3NqOk9ctcxrf3QVX3wP6810DDRPdI6l e8ccG64Ge0HjkO+aYC5+c2L/qKBzwtSbl/olJEuFU2DVxBQO+K29TTUJfxpVzC9Zf2pvT+1NRj0f 2/ofHujYZ01D6+YqI8c=</SignatureValue> <KeyInfo> <KeyValue> <RSAKeyValue> <Modulus>jfAd5uV38L36+lDZJrqfH9oLN86VJezXYfAeU+lrFoHlKAXVJLAi9hKvBHQRer4tPfdez6iSBKsl 6IHkPnVRAKt0xU99uxi5QpymsWAX3qnBqHlw9Z70PwyZ+Xysfw4Q2tK2HtSgUOhMuaUcIf9sbHvf gbvcRPgxDZZqfIzDmDU=</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> </Signature>
To have complete understanding, download complete Netbeans project having complete source code from this site.
Configuration
You can download the complete project on XML Digital Signature in java from this site or you can download from the below dropbox link.
You can configure this project in your favorite java IDE and run the standalone program available inside test source folder. This project already contains both Private Key and Public Key. If you want to generate, run the java class “TestGenerateKeys” to generate a pair of keys. You can also give the path of your own XMl file to see how XML digital signature is generated.
Conclusion
I hope you have enjoyed my post about the XML Digital Signature in java. There are also many ways you can create XML digital signature, I have provided only the way to generated enveloped digital XML signature using java API. Download the complete project and go through the source code to understand the concept and its usage. I have provided some basic links in the resource and reference section for more clarity. For any kind of issues and error feel free to contact me at debadatta.mishra@gmail.com.
Resource and Reference
- http://en.wikipedia.org/wiki/XML_Signature
- http://msdn.microsoft.com/en-us/library/ms996502.aspx
- http://www.xml.com/pub/a/2001/08/08/xmldsig.html
Please be aware of Signature Wrapping attacks (see http://www.ws-attacks.org/index.php/XML_Signature_Wrapping and http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.126.6026&rep=rep1&type=pdf)) when using Enveloped or Detached Signatures! Prefer XPath for referencing purposes instead of ids! Otherwise you will be definitely screwed…
Nicely scripted and it is and useful content for novice reader.
This is a very nice article and gives in-depth information about class 3 digital signature.Thanks for this nice article, which is a really good to read.
Hi Debdatta,
Do you have sample code that signs xml documents using ‘enveloping’ method with RSA 2048 and SHA256?
Thank you,
Vikas
Hi Vikas,
Have you done the signed xml using RSA 2048 and SHA256 ? i have the same requirement and been trying for long back but couldn’t.
Please share me if you have sample code.
Can you please share to me even ,if you have sample code?
Does it works on android?
@ Have you find the solution for andriod?
Please help me too.. if you have already find something.
I can not use this for Android Application due to the Javax API, Because android has no default support for those library (Swing etc…)
Please help me to find a solution.
Do you have any alternative for Generate Digital Signed XML file in Android.
I am facing issue while signing the XML and ds: is getting appended like this (<ds:Signature….) Please help me how I can remove namespace which is appending when I am signing the XML. I am using Java 6 version 31 currently
You can utilize XML Digital Signature to perform disengaged, encompassed, and wrapping marks and in addition to sign subjective parallel information and incorporate this inside a XML archive.
seo training in surat
What should we need to pass for privateKeyFilePath and publicKeyFilePath to generateXMLDigitalSignature method to run.
Kindly tell me, what could be the values of this parameters? we understood that signedXmlFilePath is carry the input xml file path Eg :(C:/samplefile.xml).
It is and useful content for novice reader, and also nice scripted.
such nice article thank you for sharing
how to decrypt the signature value
Thanks for sharing. Keep it up