circuit

How to Send Encrypted Data with Postman

Encrypt data with crypto-js and decrypt it with the built-in Node.js crypto module.




Photo by Bundo Kim on Unsplash

Prerequisite: Knowledge of JavaScript, Node.js, and basic knowledge of Postman

Recently, I started interacting with a project’s backend that accepts only encrypted dat — that is, plaintext is converted to ciphertext before it is sent to the backend. On the backend, the ciphertext is then decrypted back to plaintext. The backend was written with Java, so I thought about how to accomplish this with Node.js.

Since I hadn’t done such a thing before, I had to do some research to see how this was done. Once I discovered what I was looking for, I had to test my findings. And the fastest way to test an API without creating a frontend is with Postman.

According to BlazeMeter, Postman is a popular API client that makes it easy for developers to create, share, test and document APIs. This is done by allowing users to create and save simple and complex HTTP/s requests, as well as read their responses. The result — more efficient and less tedious work.

Even though I had experience with Postman, I didn’t know how to encrypt data before making a request yet. So, I began another round of research and stumbled upon a tab on Postman called **Pre-request Script. **As the name implies, it’s a script that runs just before a request is sent.

Orange underlined tabOrange underlined tab

Also, Postman is pre-installed with some popular JavaScript packages and these packages can be utilized in the Pre-request Script for manipulating data. One of those packages is crypto-js which we’ll be using to encrypt data on the Pre-request Script. Now let’s see how to encrypt data using the crypto-js AES specification in the code below:

var CryptoJS = require("crypto-js");

// Generate random 16 bytes to use as IV
var IV = CryptoJS.lib.WordArray.random(16);

var keyString = "TyJk8w3KsvKEekRs";
// finds the SHA-256 hash for the keyString
var Key = CryptoJS.SHA256(keyString);

function encrypt(data) {
  var val = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
  var encrypted = CryptoJS.AES.encrypt(val, Key, { iv: IV }).toString();
  var b64 = CryptoJS.enc.Base64.parse(encrypted).toString(CryptoJS.enc.Hex);
  return b64;
}

var data = { data: "how to send encrypted data" };

// Set local variables to postman
pm.variables.set("encrypted", encrypt(data));
pm.variables.set("IV", IV.toString());

I’m going to assume you have Postman open already. So, navigate to the **Pre-request Script **tab and copy-paste the above code into it. Now, let’s step through the code.

We simply require crypto-js on line 1 since the package exists on Postman. And for an AES (AES256 by default) encryption, we need a key of 32 bytes (256 bits) and iv of 16 bytes (128 bits), so on line 4, we generate 16 random bytes to use as the IV(Initialization Vector).

Initialization vectors should be unpredictable and unique, typically required to be random or pseudorandom — Ciphers

On line 8 , we find the sha-256 hash of the key string, this returns 32 bytes (256 bits) that is used as the key . Now that we have a key and iv , we move into the encrypt function. On line 11 , we first convert data, which will be an object, to a string with JSON.stringify, and then we convert the resulting string to a word array so that the AES.encrypt method will be able to process it.

From line 12 to 14 , we pass in the key, iv, and val(which is now a word array) into the AES encrypt method and finally convert it to base64 and that completes the declaration of the encrypt function.

Now, it’s time for us to use the encrypt function and that’s what we do on line 20, the JSON data on line 17 which will be our raw request data, is passed as an argument to the encrypt function and the resulting base 64 string is set in a Postman local variable named “encrypted”. Also, the IV (Initialization Vector) has to be passed to the backend and that’s what we do on line 21, IV is converted to a string and then set on another Postman local variable named “IV”.

This then brings us to the completion of our Pre-request Script. Now let’s see how we’ll use the 2 Postman local variables (“encrypted” and “IV”) in the request body.

Firstly, we switch to the body tab on Postman and set the data format to JSON.

body tab on postmanbody tab on postman

Then we add a request body and access the Postman local variables from our pre-request script by wrapping the variable name in double-curly braces like so {{variable_name}}. We have two local variables in our pre-request script (“encrypted” and “IV”). Let’s see how we access them below.

{

   "encrypted": "*{{encrypted}}*",

   "IV": "*{{IV}}*"

}

In the code above, we access the “encrypted” local variable value by wrapping it in double-curly braces(*{{encrypted}}) *and then setting it to the JSON key named “encrypted” (the JSON key can be named whatever you wish). The same is done for the local variable “IV”. Now we’re ready to send encrypted data from Postman but we don’t have a backend to receive it. Let’s fix that.

Our Node.js backend has been set up on CodeSandbox. Now let’s look through what’s going on over there.

We’ll be using the built-in Node.js crypto module for decryption, and express for handling the HTTP request(s). Our next point of concern is the Decryption Handler, we destructure the request body (req.body) and pull out the “encrypted” and “IV” keys from it. Next, we find the sha256 hash of the variable “keyString”(same as the keyString used on Postman), this is equivalent to what we did with crypto-js on Postman’s pre-request script, but in this case, we get a 32 byte buffer as key , this buffered key is then used as the cryptographic key in the crypto.createDecipheriv() method.

Next, we convert the IV and encrypted data to a buffer and pass them into their respective methods and then run the decryption. You can read about how the decryption works here. Now the last thing we do is to add an extra property to the object before returning the response to verify that the request gets decrypted on the backend.

Finally, we need a way to connect to CodeSandbox from Postman and that’ll be done through CodeSandbox’s browser URL. In my case, that is https://m98ph.sse.codesandbox.io, and then the route name for the decryption handler is /decrypt, which means the final URL to use on Postman will be https://m98ph.sse.codesandbox.io/decrypt. Now Postman should look something like this.

postman pointing at codesandboxpostman pointing at codesandbox

All that’s left now is to send a POST request and we should get a response that looks like this.

Decryption responseDecryption response

Hurray! We’ve successfully encrypted data, sent it to the server, decrypted it, manipulated it, and sent back the response. Hopefully, you got a response that’s similar to this. If not, you can backtrack and see where you might have missed something.

Summary

In summary, we saw how to create a Pre-request Script on Postman, how to set values to Postman local variables, and how to utilize the local variables on the request body. We also learned how to encrypt with crypto-js on the client-side and decrypt with the Node.js crypto module on the server-side.

Additionally, we saw how we can use CodeSandbox as a server-side host, which is quite awesome if you ask me.

References and Helpful links

**P.S. — **Please don’t hesitate to drop your questions and suggestions below. You can also reach me on Twitter if you want to ask me personally or connect.

Thanks for reading!




Continue Learning