jagmitg
jagmitg

Reputation: 4566

AES 256 encryption PHP with Padding

I got the following requirements for the encryption for the API i am currently trying to access:

Everytime i submit to the API with the encryption, there seems to be something wrong with the API (unfortunately no error is produced).

$Data = "GOOD!";
$aesKey = "1234567812345678";

$EncryptedData = encrypt($aesKey,$Data);
$DecryptedData = decrypt($aesKey,$EncryptedData);

echo "Orignal Data : ". $Data;
echo "<br/>";
echo "After encryption = ". $EncryptedData;
echo "<br/>";
echo "After decryption = " .$DecryptedData;

function encrypt($aesKey, $dataToEncrypt) {
    $output = false;
    $iv = '{{{{{{{{{{{{{{{{';
    $output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
    OPENSSL_RAW_DATA, $iv);
    $output = base64_encode($output);
    return $output;
}

function decrypt($aesKey, $dataTodecrypt) {
    $output = false;
    $iv = '{{{{{{{{{{{{{{{{';
    $dataTodecrypt = base64_decode ($dataTodecrypt);
    $dataTodecrypt = $output = openssl_decrypt($dataTodecrypt, 'AES-128-CBC',
    $aesKey, OPENSSL_RAW_DATA, $iv);
    return $output;
}

Questions:

Upvotes: 4

Views: 15652

Answers (2)

Artjom B.
Artjom B.

Reputation: 61952

AES 256 is fine but what exactly does block size mean?

AES has a fixed block size of 128 bit. A block cipher only works on one block of a specific size. A mode operation extends a block cipher with the ability to work on multiple blocks and a padding enables it to work on plaintexts that are not a multiple of the block size.

AES-128-CBC means AES with key size of 128 bit and the CBC mode of operation. If you want to use AES-256, then you need to tell OpenSSL that: AES-256-CBC. Additionally, you need to use a key that is actually 256 bit long. Your current key is only 128 bit long.

What exactly is PKCS7 padding method and can be implemented with php?

openssl_encrypt() already does PKCS#7 padding for you and openssl_decrypt() removes it for you.

What exactly does IV do?

A random IV randomizes the ciphertext which means that encrypting the same plaintext with the same key, but a different IV produces a different ciphertext which is indistinguishable from random noise or other the same encryption with a different IV. Wikipedia has a good description what this actually does.

Keep in mind that an IV must be randomly generated for each iteration. Otherwise, an attacker who observes only the ciphertext may discover that you encrypted the same plaintext multiple times.


Keep in mind that an AES key is supposed to be quite noisy with high entropy. "12345..." looks more like a password. If you want to use passwords, then you need to derive a key from that password. PBKDF2 is a good idea with a random salt and a lot of iterations.

Upvotes: 10

jas-
jas-

Reputation: 1801

What exactly is PKCS7 padding method and can be implemented with php?

I am not really certain 'padding' is the phrase you mean here. While the PKCS#7 format does rely on padding, the example you provide has absolutely nothing to do with asymmetric encryption and the ASN.1 format for the PKCS#7 messaging syntax mentioned.

AES 256 is fine but what exactly does block size mean?

Block size is the bit size an encryption cipher, like AES-256, operates on per permutation.

What exactly does IV do?

An IV is short for initialization vector or for some symmetric encryption cipher implementations it can also be referred to as an nonce.

Both are used to help strengthen the resulting cipher text. You can think of them as being similar to a salt for a non-reversible hashing algorithm.

You should avoid re-using the same IV.

In regards to your example; the documentation for openssl_encrypt() states the following function usage:

string openssl_encrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )

Your encryption of the plain text looks accurate (while I would choose AES-256-GCM vs. AES-128-CBC as the algorithm, blocksize & mode):

$output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
    OPENSSL_RAW_DATA, $iv);

Without testing I am assuming you are getting a valid base64 encoded value.

The manual for the openssl_decrypt() method states the following usage:

string openssl_decrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )

While technically your implementation is correct; I would suggest the following (note the double assignment to $dataTodecrypt = $output = openssl_decrypt()):

$output = openssl_decrypt(base64_decode($dataTodecrypt), 'AES-128-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);

Upvotes: 0

Related Questions