Encrypted REST – API Performance Testing using JMeter

Archive for October, 2020

Encrypted REST – API Performance Testing using JMeter

Posted by KISHORE | Posted On October 15th, 2020 | API Testing, Performance Testing, QA

RESTAPI
aes_encryption_requst_response

aes_encryption_requst_response

The Problem Statement

It’s becoming more common practice in developing end-to-end encrypted REST APIs or Microservices (i.e. request/response body, headers, and even request URL paths are being encrypted) to enhance security, especially, in the industries such as finance, banking, insurance, healthcare, legal tech, travel, etc.  Now, let’s imagine a scenario where API is being completely encrypted for additional security. Then the ultimate question arises – will you be able to handle this encryption scenario and still perform the testing using JMeter? The answer is YES!!

Possible solution

User JMeter JSR223 PreProcessor and JMeter JSR223 PostProcessor to encrypt or decrypt request/response body/headers/URLs.

You can also achieve the same using other API/Performance Test automation tools, such as Katalon Studio, SaopUI, Postman, Load Runner, etc.

Encryption/Description Algorithm to be used

create aeslib.groovy file with the following code

def  encrypt (def plainText) {GroovyShell shell = new GroovyShell()

def cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”.getBytes(“UTF-8”), “SunJCE”)

SecretKeySpec key = new SecretKeySpec(“put your secret key here”.getBytes(“UTF-8”))
, “AES”)

IvParameterSpec iv = new IvParameterSpec(“put your IV key here”)

cipher.init(Cipher.ENCRYPT_MODE, key, iv)

def result = cipher.doFinal(plainText.getBytes(“UTF-8”)).encodeBase64().toString()

def ivString = cipher.getIV()

ivString = new String(ivString, “UTF-8”)

return result

}

def decrypt (def cypherText) {

byte[] decodedBytes = cypherText.decodeBase64()

def cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”, “SunJCE”)

SecretKeySpec key = new SecretKeySpec(“put your secret key here”.getBytes(“UTF-8”), “AES”)

cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(“put your IV key here”.getBytes(“UTF-8”)))

return new String(cipher.doFinal(decodedBytes), “UTF-8”)

}

 

AES encrypted Request / Parameters / URL / Header

Let’s take a real-world scenario to solve this problem, Let’s assume the following scenarios exist in your project, then how do we go ahead with the API automation

HTTP Request Body (JSON) is encrypted

HTTP Response Body (JSON) is encrypted

HTTP Request Headers are encrypted

HTTP Response Headers are encrypted

HTTP Request URL is encrypted

 

How to encrypt Request URL

In JSR223 PreProcessor  write the below code

   def aesLib = shell.parse(new File(“${System.getProperty(“user.dir”)}/scripts/aeslib.groovy”))

sampler.setDomain(“api.example.com”)

sampler.setPath(“${aesLib.encrypt(<URL path here >)}”)

How to encrypt Request Headers

In JSR223 PreProcessor  write the below code

sampler.getHeaderManager().add(new Header(“x-access-token”, aesLib.encrypt(“your token here”)))

 

How to encrypt Request Body (POST request)

def requestPostData = ‘{“param1″:”Value”,”param2″:1234,”param3″:”en”}’

def requestPostDataJOSN = ‘{“data”:”‘ + aesLib.encrypt(requestPostData) + ‘”}’

ctx.getCurrentSampler().getArguments().getArgument(0).setValue(requestPostDataJOSN);

 

How to decrypt Response Body

def encryptedResponseData = ctx.getPreviousResult().getResponseDataAsString()

def JSONResponse = aesLib.decrypt(encryptedResponseData )

def jsonSlurper = new JsonSlurper()

def jsonParsedObj = jsonSlurper.parseText(JSONResponse)

def is_success = jsonParsedObj.success

log.info  “success: ” + jsonParsedObj.success

vars.put(“dept_id”, “${jsonParsedObj.data[0].dept_id}”)

 

Conclusion

you get some ideas on how to encrypt the entire API request body in AES encoding. AES encryption is touched upon in this article.

JSR223 Pre-processor is comfortable with any of these 5 languages – Groovy, JavaScript, JRuby, Jython, and Kotlin.

Another alternative for JSR223 Pre-processor is to use the BeanShell.

BeanShell is a small, free, embeddable Java source interpreter with object scripting language features, written in Java. BeanShell dynamically executes standard Java syntax and extends it with common scripting conveniences such as loose types, commands, and method closures like those in Perl and JavaScript.