Signing SOAP Messages - Generation of Enveloped XML Signatures
Join the DZone community and get the full member experience.
Join For Free
Digital signing is a widely used mechanism to make digital contents
authentic. By producing a digital signature for some content, we can let
another party capable of validating that content. It can provide a
guarantee that, is not altered after we signed it, with this validation.
With this sample I am to share how to generate the a signature for SOAP
envelope. But of course this is valid for any other content signing as
well.
Here, I will sign
I am using Apache Santuario library for signing. Following is the code segment I used. I have shared the complete sample here to to be downloaded.
The signed SOAP message looks as follows.
Cheers!
- The SOAP envelope itself
- An attachment
- Place the signature inside SOAP header
I am using Apache Santuario library for signing. Following is the code segment I used. I have shared the complete sample here to to be downloaded.
public static void main(String unused[]) throws Exception { String keystoreType = "JKS"; String keystoreFile = "src/main/resources/PushpalankaKeystore.jks"; String keystorePass = "pushpalanka"; String privateKeyAlias = "pushpalanka"; String privateKeyPass = "pushpalanka"; String certificateAlias = "pushpalanka"; File signatureFile = new File("src/main/resources/signature.xml"); Element element = null; String BaseURI = signatureFile.toURI().toURL().toString(); //SOAP envelope to be signed File attachmentFile = new File("src/main/resources/sample.xml"); //get the private key used to sign, from the keystore KeyStore ks = KeyStore.getInstance(keystoreType); FileInputStream fis = new FileInputStream(keystoreFile); ks.load(fis, keystorePass.toCharArray()); PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray()); //create basic structure of signature javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(attachmentFile); XMLSignature sig = new XMLSignature(doc, BaseURI, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1); //optional, but better element = doc.getDocumentElement(); element.normalize(); element.getElementsByTagName("soap:Header").item(0).appendChild(sig.getElement()); { Transforms transforms = new Transforms(doc); transforms.addTransform(Transforms.TRANSFORM_C14N_OMIT_COMMENTS); //Sign the content of SOAP Envelope sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1); //Adding the attachment to be signed sig.addDocument("../resources/attachment.xml", transforms, Constants.ALGO_ID_DIGEST_SHA1); } //Signing procedure { X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias); sig.addKeyInfo(cert); sig.addKeyInfo(cert.getPublicKey()); sig.sign(privateKey); } //write signature to file FileOutputStream f = new FileOutputStream(signatureFile); XMLUtils.outputDOMc14nWithComments(doc, f); f.close(); }At first it reads in the private key which is to be used in signing. To create a key pair for your own, this post will be helpful. Then it has created the signature and added the SOAP message and the attachment as the documents to be signed. Finally it performs signing and write the signed document to a file.
The signed SOAP message looks as follows.
<soap:Envelope xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:pj="http://www.pjxml.org/namespaces/messageHeader" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"> <soap:Header> <pj:MessageHeader pj:version="1.0" soap:mustUnderstand="1"> <pj:From> <pj:PartyId pj:type="ABCDE">FUN</pj:PartyId> </pj:From> <pj:To> <pj:PartyId pj:type="ABCDE">PARTY</pj:PartyId> </pj:To> <pj:CPAId>uri:www.pjxml.org/socialService/Ping</pj:CPAId> <pj:ConversationId>FUN PARTY FUN 59c64t0087fg3kfs000003n9</pj:ConversationId> <pj:Service>uri:www.pjxml.org/socialService/</pj:Service> <pj:Action>Ping</pj:Action> <pj:MessageData> <pj:MessageId>FUN 59c64t0087fg3kfs000003n9</pj:MessageId> <pj:Timestamp>2013-10-22T17:12:20</pj:Timestamp> </pj:MessageData> </pj:MessageHeader> <pj:Via pj:id="59c64t0087fg3ki6000003na" pj:syncReply="False" pj:version="1.0" soap:actor="http://schemas.xmlsoap.org/soap/actor/next" soap:mustUnderstand="1"> <pj:Service>uri:www.pjxml.org/socialService/</pj:Service> <pj:Action>Ping</pj:Action> </pj:Via> <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#rsa-sha1"></ds:SignatureMethod> <ds:Reference URI=""> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod> <ds:DigestValue>9RXY9kp/Klx36gd4BULvST4qffI=</ds:DigestValue> </ds:Reference> <ds:Reference URI="../resources/attachment.xml"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod> <ds:DigestValue>3JcccO8+0bCUUR3EJxGJKJ+Wrbc=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>d0hBQLIvZ4fwUZlrsDLDZojvwK2DVaznrvSoA/JTjnS7XZ5oMplN9 THX4xzZap3+WhXwI2xMr3GKO................x7u+PQz1UepcbKY3BsO8jB3dxWN6r+F4qTyWa+xwOFxqLj546WX35f8zT4GLdiJI5oiYeo1YPLFFqTrwg== </ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate> MIIDjTCCAnWgAwIBAgIEeotzFjANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJMSzEQMA4GA1UE...............qXfD/eY+XeIDyMQocRqTpcJIm8OneZ8vbMNQrxsRInxq+DsG+C92b </ds:X509Certificate> </ds:X509Data> <ds:KeyValue> <ds:RSAKeyValue> <ds:Modulus> k5y0amGgOQ2O/St0Kc2/xye80tX2fDEKs2YOlM/zCknL8VgK0CbAKVAwvJoycQL9mGRkPDmbitHe............StGofmsoKURzo8hofYEn41rGsq5wCuqJhhHYGDrPpFcuJiuI3SeXgcMtBnMwsIaKv2uHaPRbNX31WEuabuv6Q== </ds:Modulus> <ds:Exponent>AQAB</ds:Exponent> </ds:RSAKeyValue> </ds:KeyValue> </ds:KeyInfo> </ds:Signature> </soap:Header> <soap:Body> <pr:GetPriceResponse xmlns:pr="http://www.pushpalankajaya.com/prices"> <pr:Price>1.90</pr:Price> </pr:GetPriceResponse> </soap:Body> </soap:Envelope>In a next post lets see how to verify this signature, so that we can guarantee signed documents are not changed.
Cheers!
SOAP
Web Protocols
XML
Published at DZone with permission of Pushpalanka Jayawardhana, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments