Securing Sensitive Data with Encryption Algorithms
Tags: encryption, php, laravel, softwaredevelopment
Published: 2024-01-28 04:21:17

Encryption is the process of converting plain text into an unreadable form(ciphertext) to protect from unauthorized access.

There are 2 types of Encryptions:

1. Symmetric-Key encryption
2. Asymmetric encryption (public-key encryption)

**How encryption algorithms work:**

**Encryption:**
Plain text is input into the algorithm.
The algorithm uses a key to perform a series of complex mathematical operations on the plain text. The output is ciphertext, which is unreadable without the key.

**Decryption:**
Ciphertext is input into the algorithm.
The algorithm uses the correct key to reverse the mathematical operations.The output is the original plain text.

**Symmetric-Key encryption:**
It uses the same key for both encryption and decryption. It is fast and efficient for large amounts of data. Secure keys are exchanged between parties.

There are two main types: block ciphers and stream ciphers.

**Block Ciphers:**

1. Block ciphers encrypt data in fixed-size blocks (e.g., 64 or 128 bits) using a key.
2. A widely used block cipher is the Advanced Encryption Standard (AES), which supports key lengths of 128, 192, or 256 bits.
3. The data is divided into blocks, and each block is encrypted independently.

**Stream Ciphers:**
Stream ciphers encrypt data bit by bit or byte by byte, typically in a continuous stream.
One common stream cipher is the Rivest Cipher (RC4).

**Example: AES (Advanced Encryption Standard)**

```
function encrypt($data="", $key="") {
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-cbc")); // dynamic iv (we can also set static iv)
    $encrypted = openssl_encrypt($data, "aes-256-cbc", $key, 0, $iv);
    return base64_encode($iv . '!!' . $encrypted);
}
function decrypt( $data="", $key="") {
    list($iv, $encryptedData) = explode('!!', base64_decode($data), 2);
    return openssl_decrypt($encryptedData, "aes-256-cbc", $key, 0, $iv);
}

$plainData = [
    'email' => 'codewithrubab@gmail.com',
    'password' => 'codeOn@Vscode2024';
];
$saltKey = "asdckd44dbc228e16c2888436d17a";

$encryptedData = encrypt(json_encode($plainData), $saltKey);
echo $encryptedData;
$decryptedData = decrypt($encryptedData, $saltKey);
print_r($decryptedData);
```
Note: If we need to re-generate same encrypted data on same plain text then we need to always use same Salt Key and IV. Otherwise, the output will be different.

**Asymmetric encryption (public-key encryption):**
It uses two different keys: a public key for encryption and a private key for decryption.

we don’t need secure key exchange for encryption. It’s slower than symmetric encryption and useful for digital signatures and authentication,

Common public-key encryption techniques: RSA, ECC (Elliptic Curve Cryptography), Diffie-Hellman.

Let’s see an Example with RSA Algorithm.

If we don’t have the public and private keys then we can generate from the command line interface.

For private key file generation in a directory:

`openssl genrsa -out privateKey.pem 2048`
For public key:
`openssl rsa -in privateKey.pem -pubout`

Here, privateKey.pem and privateKey.pem are the generated file names.

The generated public key is a RSA result.

The private Key is not a RSA result. To make it a RSA result we need to write some code.

First, install this package in your Laravel Project.

`Composer require "phpseclib/phpseclib": "~2.0"`

```
use phpseclib\Crypt\RSA;


// private key: pem to rsa code
$privateKey = 'set pem file data';
$rsa = new RSA();
$rsa->loadKey($privateKey);
$rsaPrivateKey = $rsa->getPrivateKey();
dd($rsaPrivateKey);
```
Additionally, if we need to convert a public key from pem to RSA then we can convert using this code.

```
// for public key: pem to rsa.
$publicKey = 'set pem file data';
$rsa = new RSA();
$rsa->loadKey($publicKey);
$rsa->setPublicKey($publicKey);
$rsaPublicKey = $rsa->getPublicKey();
dd($rsaPublicKey);
```
**Let’s see a real life implementation of Asymmetric Encryption:**

Let’s assume we are making a transaction with a bank as a merchant. Bank provided us a public key and we have shared our public key to the bank. From our end, we will encrypt our transaction request data using our private key and send it to the bank. Bank will decrypt the data using our provided public key. Bank then process the data and send us an encrypted response using their private key. After receiving the bank’s response we will decrypt using their public key to get the plain response.

In addition to that, Bank has asked us to send a signature with every transaction request. They also told us that we need to decrypt the decoded Sensitive Data using Merchant Private Key with PKCS1Padding Algorithm. The signature will be generated using SHA256withRSA signature algorithm.

Now, We will make an api call to initiate a transaction to the bank’s end.

```
public  function signatureGenerate($data){
   $private_key = "-----YOUR RSA PRIVATE KEY-----";
   openssl_sign(json_encode($data), $signature, $private_key, OPENSSL_ALGO_SHA256);
   return base64_encode($signature);
}   


public function encryptDataWithPublicKey($data){
   $public_key = "-----YOUR PUBLIC KEY-----";
   openssl_public_encrypt(json_encode($data), $encryptedData, $public_key, OPENSSL_PKCS1_PADDING);
   return base64_encode($encryptedData);
}


public function decryptDataWithPrivateKey($cryptText){
   $private_key = "-----YOUR RSA PRIVATE KEY-----";
   openssl_private_decrypt(base64_decode($cryptText), $plainText, $private_key, OPENSSL_PKCS1_PADDING);
   return json_decode($plainText, true);
}


public function HttpPostMethod($postURL, $postData, $authToken = null)
{
   try {
       $curl = curl_init($postURL);
       $postData = json_encode($postData);
       $header = array(
           'Content-Type:application/json'
       );
      
       if($authToken){
           $header[] = 'token:' . $authToken;
       }


       curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
       curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
       curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
       curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
       curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
       curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
       curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);


       $resultdata = curl_exec($curl);


       $err = curl_error($curl);
       $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
       $curlErrorNo = curl_errno($curl);


       $ResultArray = json_decode($resultdata, true);
       curl_close($curl);
       return $ResultArray;
   } catch (\Exception $exception) {
       echo 'Failed to Connect with Bank. Please try again later';
       exit;
   }


}


initTransaction($merchantId, $merchantAccountNumber, $orderId){
   $postUrl = 'api.your-bank.com/api/payment/initialize';
   $plainData = array(
       'merchant_id' => $merchantId,
       'order_id' => $orderId
   );
   $postData = array(
       'account_number' => $merchantAccountNumber,
       'sensitiveData' => $this->encryptDataWithPublicKey($sensitiveData),
       'signature' => $this->signatureGenerate($sensitiveData)
   );


   return $this->HttpPostMethod($postUrl, $postData);
}
$encryptedResponse = $this->initTransaction('MER1234', 'ACC12345', 'ORD123456');
$plainResponse = $this->decryptDataWithPrivateKey($encryptedResponse['sensitiveData']);
dd($plainResponse);
```
Bonus:
Here is a useful link to [RSA Signature/Generation & Validation](https://8gwifi.org/RSAFunctionality?rsasignverifyfunctions=rsasignverifyfunctions&keysize=2048)

**Things to consider when choosing an Encryption Algorithm:**

1. Level of security required.
2. Speed of encryption/decryption.
3. Key management complexity.
4. Resource constraints.

**Where encryption algorithms are used**

1. Secure communication (e.g., emails, VPNs)
2. Data storage (e.g., databases, file systems)
3. Financial transactions (e.g., online banking)
4. Password protection
5. Digital signatures

----------------------------------------

Thank you for reading my article. You can join [code with rubab](https://www.facebook.com/groups/codewithrubab) for web development-related queries & discussions.

Also, you can find me on:

[Linkedin For Regular Posts](https://www.linkedin.com/in/imran-hossain-rubab/)

[My website](https://codewithrubab.com/)

[My Facebook Page](https://www.facebook.com/codewithrubab)

[My Youtube Channel](https://www.youtube.com/@codeWithRubab)