Encrypt Specific XML Tags With The Power Of DataWeave

DataWeave is a powerful language, and the possibilities of what you can do with it are infinite.

In this blog post, I am going to show you how to select specific data inside a series of specified tags.

For example, in this case we want to encrypt data inside sensitive XML tags such as an SSN, a credit card number, etc.

We define an array with the XML tags to be encrypted named keyToEncrypt (we are encrypting just the contents, not the whole line including the tag)

Then we define a function, to send the matching contents to a separate flow where the encryption actually happens.

After that, we define another function to determine if the tag we read is part of our keyToEncrypt array, if so, the sizeOf method will return a result greater than 0 (this ignores schemas such as <web:superTag>, the function will match anyway even if we just search for “superTag” alone)

Here comes the star of the show: the function maskSensitiveData will go through the tags and levels trying to match the element of our array, and when it matches one, it will send it to the function encrypt and re-assemble the XML tag content passed, replacing that data with “*****”, as we specified.

Here, instead of returning asterisks, you can easily call a (private) Flow that encrypts that data passed with your desired encryption method, using the lookup method.
It would look something like this:

%function encrypt(val) lookup(“encryptFlow“,val)

We create the encrypt function, which gives the passed val value, to the encryptFlow flow.

Here’s a link that helps you create an encryption flow using PGP: PGP Encryption Using Anypoint Studio

The full DataWeave code will look something like this:

%dw 1.0
%output application/json

%var keyToEncrypt = ['ssn','creditCardNumber']

%function encrypt(val) "*****"

%function needsEncrypt(key) (sizeOf (keyToEncrypt find key)) > 0

%function maskSensitiveData(value) value mapObject ({
($$) : maskSensitiveData($) when $ is :object otherwise $
} unless needsEncrypt($$ as :string) otherwise {
($$) : encrypt($)
})
---

maskSensitiveData(payload)

For the ones interested in calling the encrypting flow with DataWeave, here is the DataWeave code with the call:

%dw 1.0
%output application/xml

%var keyToEncrypt = ["ssn", "creditCardNumber"]

%function encrypt(val) lookup("encryptFlow",val)

%function needsEncrypt(key) (sizeOf (keyToEncrypt find key)) > 0

%function maskSensitiveData(value) value mapObject ({
 ($$) : maskSensitiveData($) when $ is :object otherwise $
} unless needsEncrypt($$ as :string) otherwise {
  ($$) : encrypt($)
})

---

maskSensitiveData(payload)  

This way, we re-assemble the XML, but replaced the contents of the tags specified with encrypted/masked strings.

IMPORTANT NOTE:  Always make sure that the mime-type that the transform-message component is receiving, it set correctly, in this case application/xml
To do this you can simply set it previously when you create the message that is going to be the input of that transform-message component.
Or you can force it in the configuration XML of the DataWeave input-payload:

 


 

Let me show you an example.

 

Let’s take this XML formatted personal information example we might want to protect, and run it through our DataWeave code:

Sample Input Data

 

 

 

The DataWeave code as seen on Anypoint Studio:

DW Code

The data output as a JSON Array, as we specified previously in our output variable in the DataWeave code:

Screen Shot 2016-02-24 at 4.21.43 PM

As you can see, the fields ssn and creditCardNumber, which were members of our keyToEncrypt array, are now masked with the specified “*****” mask.

 

This has been fully tested with:

 

Download the Full Working Example

Link to Download the Full Working Example: Download Now!

 


We'd love to hear your opinion on this post


12 Responses to “Encrypt Specific XML Tags With The Power Of DataWeave”

  1. I think this is a great article. I find this very resourceful. I do think, rather, it is not encrypting, but masking specific XML tag contents. This serves my purpose, regardless.

    • Hello Tom!
      It does mask the data, but as it uses encryption in this case, PGP, I decided to go with Encryption as a title instead of “Masking with encrypted data”. But yes, you are right, the encryption results in masking the specific tags, it is just a title thing.

  2. this DW script doesn’t work as-is

    • Hello Paul,

      Could you please specify the part that does not work or the error returned?

      We appreciate the feedback! Thanks!

    • The DataWeave Code Snippet was updated. Thanks for the feedback!

  3. implication here is is incorrect – it doesn’t work with a sub-flow; it works if a normal flow is used

    • Hello Paul,

      You can call a sub-flow with a FlowRef element with no issues.
      Can you explain this statement a little further?

      Thanks!

    • The DataWeave Code Snippet was updated. Thanks for the feedback!

  4. Could you please check a example url. I could not access it ( 404 error ). Thanks for great topic.

  5. Hi, How to handle attributes. the code to mask will support elements only in XML.

    Appreciate your help.

    Regards,
    Ananda

  6. thank you, this code gave me some insight.. i was able to extend your code to make it more dynamic like externalizing fields and was able to put start and end indexes to mask. it can be found here..

    http://interestingjavaj2ee.blogspot.com/