How to create a rest API for encryption and decryption in Drupal

In this article, I am explaining one of the requirements where developers are asked to encrypt  API keys and sensitive data which is stored in a database or in any PHP file of your custom module.  Also, we will create a rest API endpoint for encryption and decryption.

The main reason for this requirement is related to security, suppose if there any security breach occurs, and attackers got access to all files in the Drupal project directory, in this case, attackers can easily read the API key or other credentials from PHP files if it is in human-readable form.

So in this article, we will discuss how we will encrypt our secret keys and other confidential data using contributed modules and also we will create a Rest API for encryption and decryption.

We will do this in the below steps.

  1. Configure contributed modules for encryption

In this step, we will install and configure modules Encrypt, key, and Real RES module.

  1. Create a  Rest API endpoint for encryption  and decryption

Here will create  Rest API endpoint for encryption and decryption

You can read more about Rest API  core module and creating custom Rest API here

 Configure contributed modules for encryption

 Step 1 – install the encrypt module

Real aes module has a dependency on encrypt module. so we have to install encrypt module first.

https://www.drupal.org/project/encrypt

Step 2 –install  and configure real_aes and key module

We are going to configure Encryption module real_aes and key module.

Encryption Method – [Real AES](https://www.drupal.org/project/real_aes)

Some encryption method module is required to be able to use the Key and Encrypt

Modules.

Install key module (https://www.drupal.org/project/key)

Then enable key and RealAES module

Real RES module need   Defuse PHP-Encryption library so you have to install this module using below composer command

composer require drupal/real_aes

next we are going  to generate an encryption key using command prompt. This is needed in key configuration window.

 

Configuration -> System->keys

 

Generate a base64 key in command line.

Use below command in linux.

`dd if=/dev/urandombs=32 count=1 | base64 -i – > /var/www/html/your_project/encrypt.key`

Visit the Keys module’s configuration page and click “Add Key”.

Provide information’s below.

 

Next step is to define encryption profiles.

The encrypt module allows the site owner to define encryption profiles that can be reused throughout Drupal website.

We already installed encryption module. Navigate to below page

Configuration ->system->encryption profile

click on  “Add Encryption Profile”

Click on Add Encryption profile.

Fill below details.

  • Label your Encryption Profile
  • Encryption method: “Authenticated AES (Real AES)” – or the encryption method

of your choice.

  • Encryption Key: Select the Key you created in the previous step.
  • Save

Now all configurations completed.next you can test encryption and decryption in Encryption profile.

GO to Encryption profile you just created, click on edit arrow you can see Test link.

Click on the test link.

You can test encryption and decryption here as shown below.

Create Rest API for encryption and decryption

Next we are going to create a Rest API resource for encryption and  decryption.

So final output will be like as below.

Decrypt request

url –  http://localhost/your-project/rest/digitalnadeem/api/encrypt-decrypt/items?_format=json

Request body

{"encrypt_profile":"encrypt_profile","action":"decrypt","input_text":"def50200a999e41579b33e98b4145b042599c97d144d8f7463fb7d93c49e76395b2406a2bdf909d3f32bbcc19f5149fcb80f7c994e21712e065e08540c79b16f2e7d7f07757202eb5da9a68dcff1570d808f090f3c0f4a4c911bf96a16"}

Response

{

    "message": "success",

    "encrypted_string": "",

    "decrypted_string": "nadeem-is"

}

Encrypt request

url –  http://localhost/drupalparagraph/rest/digitalnadeem/api/encrypt-decrypt/items?_format=json

{"encrypt_profile":"encrypt_profile","action":"decrypt","input_text":"nadeem-is"}

Response

{

    "message": "success",

    "encrypted_string": " def50200a999e41579b33e98b4145b042599c97d144d8f7463fb7d93c49e76395b2406a2bdf909d3f32bbcc19f5149fcb80f7c994e21712e065e08540c79b16f2e7d7f07757202eb5da9a68dcff1570d808f090f3c0f4a4c911bf96a16",

    "decrypted_string": ""

}

So for achieving this we are going to create Rest resource in our custom module.

You can refer this article for creating a sample Rest resource for POST.

Using encrypt module we can encrypt and decrypt input string using below service.

For encryption

$instance_id = “encryption_profile”

$encryption_profile = EncryptionProfile::load($instance_id);

$encrypted = \Drupal::service('encryption')->encrypt($string, $encryption_profile);

 

For decryption

$instance_id = “encryption_profile”

$encryption_profile = EncryptionProfile::load($instance_id);$decrypted = \Drupal::service('encryption')->decrypt($string, $encryption_profile);

here  $instance_id  is the machine name of your encryption profile created in first step.

For creating above mentioned rest end point create a php file in below path in your custom module.

\src\Plugin\Rest\Resource\RestEncryptDecrypt.php

First include encryption profile before starting the class after other use statements.

namespace Drupal\digital_nadeem\Plugin\rest\resource;


use Drupal\rest\ModifiedResourceResponse;

use Drupal\rest\Plugin\ResourceBase;

use Drupal\rest\ResourceResponse;

use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

use Drupal\encrypt\Entity\EncryptionProfile;

then provide declaration to identify resource Id and path to API resource as shown in below.

/**

 * Provides a resource to get view modes by entity and bundle.

 *

 * @RestResource(

 *   id = "rest_sampleencrypt",

 *   label = @Translation("Rest sampleencrypt"),

 *   uri_paths = {

 *     "https://www.drupal.org/link-relations/create" = "/rest/digitalnadeem/api/encrypt-decrypt/items"

 *    

 *   }

 * )

 */

Here   “http://your_proj/rest/digitalnadeem/api/encrypt-decrypt/items  will be URL of the API that we are creating now.

then declare class by extending  resourceBaseclass

class RestEncryptDecrypt extends ResourceBase {

So in this file we are adding below code in our post function.

public function post($data) {


$response_data = ['message' => 'success','encrypted_string'=>'','decrypted_string'=>''];
$instance_id = $data['encrypt_profile'];
if($data["action"] == "encrypt"){ //===if action parameter has encrypt values execute this section

//$instance_id = 'encrypt_profile';
try{

$string = $data['input_text']; //====input string parameter to be encrypted
$encryption_profile = EncryptionProfile::load($instance_id);
$encrypted = \Drupal::service('encryption')->encrypt($string, $encryption_profile);
$response_data['encrypted_string'] = $encrypted; //===output assings to response array
}catch(Exception $e){
\Drupal::logger('type')->error($e->getMessage());
$response_data['message'] = 'Something went wrong';
}

}else if($data["action"] == "decrypt"){ //===if action parameter has decrypt values execute this section
try{ 
$string = $data['input_text']; //input string parameter to be decrypted
$encryption_profile = EncryptionProfile::load($instance_id);
$decrypted = \Drupal::service('encryption')->decrypt($string, $encryption_profile);
$response_data['decrypted_string'] = $decrypted;
}catch(Exception $e){
\Drupal::logger('type')->error($e->getMessage());
$response_data['message'] = 'Something went wrong';
}
}

$response = new ResourceResponse($response_data);
// In order to generate fresh result every time (without clearing 
// the cache), you need to invalidate the cache.
$response->addCacheableDependency($response_data);
return $response;
}

So here based parameter action we are executing encryption and decryption codes and providing output in a response.

Now clear the cache and go to    Configuration ->web Services -> Rest

http://your-proj/admin/config/services/rest

In Rest UI , you can see our newly created resource under disabled resource list. You can enable this resource and I have selected below options.

And hit save button. Also if you want to access API URL without any authentication you have to allow access for anonymous user in permission page as shown below.

See below screen in permissions page.

you can read this article to see how we can implement authentication in Rest API.

Now go to your Postman or Rest client window

For decryption request

decryption response

For encryption request

Encryption response

Here encryption_profile is the machine id of encryption profile created in first step.

You can download source code of this sample module here

Conclusion

Even though Drupal has robust security features , security teams are concerned with keeping hard corded personal data and other confidential information in PHP files and in databases. Here you can use  this Rest API anywhere in your application. Also you can use this for other third party applications.

 



Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...