Encryption & Decryption With PHP MCrypt Using Rijndael 256

"Encryption Description with PHP"

Almost all the Internet is API based currently. APIs have been Integral part of all Systems. Data is being transferred from Server to Server, Web to Web, Device to Device via API Calls. So in this Era of API Centric application Security remains a very critical issue while transferring data from Server to Client or vice versa. Even if we are not sending Via APIs then also Data Security in very Important while storing the sensitive information of user data line Password, Credit Card numbers etc.

Almost all Languages provide methods to encrypt & decrypt data. We are here going to user PHP and MCrypt to build our encryption and decryption functions. Lets do some background study for the Libraries and standards that we are going to use.

  1. MCrypt
  2. Rijndael (256)
  3. IV – Initialisation Vector
  4. CBS – Cipher Block Chaining

MCrypt

PHP MCrypt is an interface to the mcrypt library, which supports a wide variety of block algorithms such as DES, TripleDES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2 and GOST in CBC, OFB, CFB and ECB cipher modes. MCrypt is a replacement for the old crypt() package and crypt(1) command, with extensions. It allows developers to use a wide range of encryption functions, without making drastic changes to their code. It allows users to encrypt files or data streams without having to be cryptographers.

Rijndael

Rijndael algorithm, is a new generation symmetric block cipher that supports key sizes of 128, 192 and 256 bits, with data handled in 128-bit blocks – however, in excess of AES design criteria, the block sizes can mirror those of the keys. Rijndael uses a variable number of rounds, depending on key/block sizes, as follows: 9 rounds if the key/block size is 128 bits 11 rounds if the key/block size is 192 bits 13 rounds if the key/block size is 256 bits It has been selected by the U.S. National Institute of Standards and Technology (NIST) as the candidate for the Advanced Encryption Standard (AES). We will be currently using Rijndael 256 for encrypting our data.

IV – Initialisation Vector

Initialisation Vector (IV) or Starting Variable (SV) is random set of Characters that is used along with the Secret key to encrypt data. It is always supposed to be random so that even repeated use of same data and key never produces the same encryption, so that no one can track and understand the patterns of encryption.

CBS – Cipher Block Chaining

In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block depends on all plaintext blocks processed up to that point. Due to it’s this property it creates a unique hash every time even for the same source data. It was invented by IBM in 1976.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
function encryptAPIData($data) {
    # key size for AES-128, 192 256 should be
    # 16, 24 and 32 byte keys respectively
    # as now we are using "MCRYPT_RIJNDAEL_256", we'll be using 32
    $key = "0cc175b9c0f1b6a831c399e26977";

    # lets serialize data before sending to encrypt
    $encrypt_data = serialize($data);

    # lets first find out what size is supported for IV
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);

    # create a random IV to use with CBC encoding
    $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);

    # now lets creates a cipher text compatible with AES (Rijndael block size = 256)
    # with CBC Mode
    $encrypted_data = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt_data, MCRYPT_MODE_CBC, $iv);

    # lets encode data to send it and attach IV with it for decryption on another end
    $encoded = base64_encode($encrypted_data) . '|' . base64_encode($iv);

    return $encoded;
  }

# corresponding Decrption function will be
function decryptAPIData($data) {
    $key = "0cc175b9c0f1b6a831c399e26977";
    $decrypt_data = explode('|', $data . '|');
    $decoded = base64_decode($decrypt_data[0]);
    $iv = base64_decode($decrypt_data[1]);
    if (strlen($iv) !== mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)) {
      return false;
    }

    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
    $decrypted = unserialize($decrypted);
    return $decrypted;
  }


# Lets test it now
echo "==================================================================\n";
$text_to_encrypt = "I'm going to encrypt this data";
echo "Original text: \t\t\t{$text_to_encrypt}\n";
$encrypted_data = encryptAPIData($text_to_encrypt);
echo "Text after encryption: \t\t" . $encrypted_data . "\n";
echo "Text after decryption: \t\t" . decryptAPIData($encrypted_data) . "\n";
echo "==================================================================\n";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Output will be:

Run 1:

==================================================================
Original text:          I'm going to encrypt this data
Text after encryption:      t1b0yPOYrapCuAsN/NhTvXoH4nsiRnSp9nWUOvDwRvebCFbE0KmeJJcwpeW/kHwQcayLDXHlO5VsR6yNPmgKhQ==|tD30TYUcQgwDgoxGyREVuXLbadJrSfVv6S6r+y+gKVA=
Text after decryption:      I'm going to encrypt this data
==================================================================
Run 2:

==================================================================
Original text:          I'm going to encrypt this data
Text after encryption:      AJJ6/ehzguuKz7fDx+5AcSoBek3SdBNkYZ/gxx5DARdv2vsYM5PLDui47f2l5H5F4NtdioUv6NLnQ7Dzf63h+w==|1YTqo3KjV6edvFBsopUyJJWA4q7DPEAfka22qS64Mog=
Text after decryption:      I'm going to encrypt this data
==================================================================
Run 3:

==================================================================
Original text:          I'm going to encrypt this data
Text after encryption:      7uDI8s3z+jiF90Qulex2f1zoylQihlauC8s8YQgKKcz6ClUlRCNEPYqxWz01gmdp9mK8eYqXRga4naEDEDRr+Q==|DZ8P+eYegzi2amGRWfDpHm2OJDkTgNQMmqJ7ZJ9edxo=
Text after decryption:      I'm going to encrypt this data
==================================================================
So we have always unique encryption even for same text. This is magic of CBC and IV

Comments