0

I'm using phplibsec to do some encryption operations. The library has a method to set the IV and I'm using it to generate a random initialization vector to use in encrypt operations. The problem is that I need to have the same IV to decrypt the data (I didn't know this aspect). Now after small code modification I want to prepend the generated IV to the encrypted data but I don't know how to proceed.

encrypt.php

use phpseclib\Crypt\AES;
use phpseclib\Crypt\Random;

$payload = [];
// new phpseclib AES instance
$cipher = new AES();
// set a password for the encrypt
$cipher->setPassword($password);
// IV creation
$iv = Random::string($cipher->getBlockLength() >> 3);
// this method of the library will make the forst part of my data unreadable without iv
$cipher->setIV($iv);
// encrypt data - here I want to prepend the iv to get it later on decrypt
$output = $cipher->encrypt("some data");
// push encrypted data into an array
array_push($payload, $output);

decrypt.php

use phpseclib\Crypt\AES;
use phpseclib\Crypt\Random;

$cipher = new AES();
$cipher->setPassword($password);
// here is my mistake - I'm creating a new IV but I need the same
$cipher->setIV(Random::string($cipher->getBlockLength() >> 3));
// opening the file that hold encrypted data
$payload = file_get_contents('myencrypted.file');
// I've used the : to separate each line of encrypted data with php implode()
$exploded = explode(' : ', $payload); 
// iterating over the array that hold encrypted data to decrypt them then base64_encode before pass back to the client in json.       
foreach( $exploded as $str ){
  array_push($output, base64_encode($cipher->decrypt($str) ));
}

The decrypt operation will give me something similar (I'm encrypting images data uri)

XGG”)”>hÑÏÄr*‹base64,/9j/4AAQSkZJRgABAgAAAQABAAD…D8

I think that this part XGG”)”>hÑÏÄr*‹ of the decrypted data is the IV? How I can prepend or append it to the encrypted data and then extrac it when the data needs to be decrypted?Can anyone help me please?

UPDATE

I've followed the suggestion of Topaco in comments and now I'm able to get back the data uri but it will have the iv attached so I need to remove it. At the moment after decrypt the data uri will have this structure:

¸ÈouFH@¬ÆÌ~k!Eâdata:image/jpeg;base64,/9j/4AAQSk

How I will remove the part before the data:image/jpeg;base64 ?

fed3vt
  • 279
  • 1
  • 4
  • 16
  • 2
    Actually this is a duplicate of [this question](https://stackoverflow.com/q/11821195). Although different libraries are used (openssl vs. phpseclib), this is irrelevant for the handling of the IV (see penultimate section of the [accepted answer](https://stackoverflow.com/a/12486940)): Concatenation of IV and ciphertext during encryption (`$iv.$output`), separation during decryption (with `substr()`). In the case of phpseclib it applies `$iv_size = $cipher->getBlockLength() >> 3;` which you already used when creating the IV. – Topaco Nov 16 '20 at 14:53
  • @Topaco Thanks for the help. If you can provide an example with phpseclib will be great. I will take a look at the question you've linked. Thank you – fed3vt Nov 16 '20 at 15:34
  • @Topaco Unfortunately the `$cipher->getBlockLength() >> 3` will give this problem `PHP Catchable fatal error: Object of class phpseclib\Crypt\AES could not be converted to string` – fed3vt Nov 16 '20 at 16:24
  • With this expression the IV size is determined in your `encrypt` method. Does the `encrypt` method not work? – Topaco Nov 16 '20 at 16:38
  • @Topaco I've solved that problem but now I'm unable to remove the IV from the decrypted data. I'm trying with `str_replace`, `but without succes – fed3vt Nov 16 '20 at 17:00
  • The IV does not need to be removed from the decrypted data. You must separate IV and ciphertext **before** decrypting: `$iv = substr($data, 0, $iv_size);` and `$ciphertext = substr($data, $iv_size);` (where `$data = $iv.$output;` is the concatenated data from the encryption). After separation the ciphertext can be decrypted (using the IV). – Topaco Nov 16 '20 at 17:11
  • I've done it in a different way. `$iv = substr($str, 0, $ivSize); $cipher->setIV($iv); $decrypted = $cipher->decrypt($str);` and this will mantain the iv attached to the decrypted data! – fed3vt Nov 16 '20 at 17:15
  • If you replace `$decrypted = $cipher->decrypt($str);` with `$ciphertext = substr($str, $ivSize);` and `$decrypted = $cipher->decrypt($ciphertext);` it should work. – Topaco Nov 16 '20 at 17:27
  • 1
    Yes, Thanks for the help. I've added another `substr()` passage and now all works fine. – fed3vt Nov 16 '20 at 17:34

0 Answers0