Problem Statement:
I’m trying to integrate API which AES/CBC/PKCS5 Padding. After some research I found the implementation on following article.
However, In this article there were using mcrypt
which is deprecated and removed from PHP 7.2. Hence, I’m looking to modify above implementation in openssl
.
There is function pkcs5_pad
for PKCS5 padding the data which require parameter as data and blocksize. And there are no alternative to mcrypt_get_block_size
in openssl.
Code Snippet
pkcs5_pad
& pkcs5_unpad
function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) return false; if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); }
Trying to convert following
$paddedData = pkcs5_pad( $data, mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC) ); $encrypteddata = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, hex2bin(md5($key)), $paddedData, MCRYPT_MODE_CBC, $iv );
TO
$paddedData = pkcs5_pad($data); // How do I getBlock size in OpenSSL. i.e. Alternate to mcrypt_get_block_size $encrypteddata = openssl_encrypt( $paddedData, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv );
Trial & Error:
I found some file after some research in Github. But didn’t know how to use this file to convert data into pkcs5
padded data.
Advertisement
Answer
The good news is – OpenSSL has a “built in” padding so you don’t have to worry about it.
The full running code below shows you how to encrypt or decrypt a string using a 32 bytes long, randomly generated key for AES-256. The AES mode is CBC, and it is using the PKCS5/7 padding. The output of the encryption is Base64 encoded (usefull for transport via Email), of course you can leave the Base64 en-/decoding out when saving the ciphertext to a file and later read the file for decryption.
Please be aware that there are is no exception handling and the code is for educational purpose:
<?php function generateRandomAesKey() { return openssl_random_pseudo_bytes(32, $crypto_strong); } function generateRandomInitvector() { return openssl_random_pseudo_bytes(16, $crypto_strong); } function base64Encoding($input) { return base64_encode($input); } function base64Decoding($input) { return base64_decode($input); } function aesCbcEncryptToBase64($key, $data) { $iv = generateRandomInitvector(); $ciphertext = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($iv) . ':' . base64_encode($ciphertext); } function aesCbcDecryptFromBase64($key, $data) { list($iv, $encryptedData) = explode(':', $data, 2); return openssl_decrypt(base64_decode($encryptedData), 'aes-256-cbc', $key, OPENSSL_RAW_DATA, base64_decode($iv)); } echo 'AES CBC 256 String encryption with random key full' . PHP_EOL; $plaintext = 'The quick brown fox jumps over the lazy dog'; echo 'plaintext: ' . $plaintext . PHP_EOL; // generate random key $encryptionKey = generateRandomAesKey(); $encryptionKeyBase64 = base64Encoding($encryptionKey); echo 'encryptionKey (Base64): ' . $encryptionKeyBase64 . PHP_EOL; // encryption echo PHP_EOL . '* * * Encryption * * *' . PHP_EOL; $ciphertextBase64 = aesCbcEncryptToBase64($encryptionKey, $plaintext); echo 'ciphertext: ' . $ciphertextBase64 . PHP_EOL; echo 'output is (Base64) iv : (Base64) ciphertext' .PHP_EOL; echo PHP_EOL; echo 'Cross platform cryptography: AES CBC 256 String encryption with random key (PHP)' . PHP_EOL; // decryption echo PHP_EOL . '* * * Decryption * * *' . PHP_EOL; $decryptionKeyBase64 = $encryptionKeyBase64; $ciphertextDecryptionBase64 = $ciphertextBase64; echo 'decryptionKey (Base64): ' . $decryptionKeyBase64 . PHP_EOL; echo 'ciphertextDecryption (Base64): ' . $ciphertextDecryptionBase64 . PHP_EOL; echo 'input is (Base64) iv : (Base64) ciphertext' .PHP_EOL; $decryptionKey = base64Decoding($decryptionKeyBase64); $decryptedtext = aesCbcDecryptFromBase64($decryptionKey, $ciphertextDecryptionBase64); echo 'plaintext: ' . $decryptedtext . PHP_EOL; ?>
The output looks like:
AES CBC 256 String encryption with random key full plaintext: The quick brown fox jumps over the lazy dog encryptionKey (Base64): DuLNOxN3BUc+htgigTcQOeJsPuMkF/aBcyVSaXhMcEw= * * * Encryption * * * ciphertext: XvXGCOyMrj2ohknIr8k1+A==:nPrEGko/7OFRjiRCgX0Hryz0a+Qc6A9RmRlipWl+R6vslqLBf/8EZtGsf+zwwGAV output is (Base64) iv : (Base64) ciphertext * * * Decryption * * * decryptionKey (Base64): DuLNOxN3BUc+htgigTcQOeJsPuMkF/aBcyVSaXhMcEw= ciphertext (Base64): XvXGCOyMrj2ohknIr8k1+A==:nPrEGko/7OFRjiRCgX0Hryz0a+Qc6A9RmRlipWl+R6vslqLBf/8EZtGsf+zwwGAV input is (Base64) iv : (Base64) ciphertext plaintext: The quick brown fox jumps over the lazy dog