undone
undone

Reputation: 7888

equivalent of mcrypt_encrypt in PhpSecLib

I have an old piece of code that's written using mcrypt extension and I have to change it to phpseclib. But my code doesn't generate the same output as mcrypt function:

Old code:

$encryptedText =mcrypt_encrypt(
        MCRYPT_RIJNDAEL_256,
        $myKey,
        $data ,
        MCRYPT_MODE_CBC,
        $myIV
    );

My new code:

$aes = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CBC);
$aes->setKey($myKey);
$aes->setIV($myIV);
$aes->disablePadding();
$seclib = $aes->encrypt( $data );

but $encryptedText and $seclib are not the same.

Upvotes: 0

Views: 1070

Answers (1)

Narf
Narf

Reputation: 14752

You're equating Rijndael with AES, a common misconception.

AES is only a subset of it - Rijndael-128, with the difference between AES variations being only the key size:

  • AES-128 is Rijndael-128 with a 128-bit key.
  • AES-256 is again Rijndael-128, but with a 256-bit key.

The suffix number in Rijndael variations on the other hand, refers to both key size and block size, so of course you cannot get Rijndael-256 by doing AES, as you need a 256-bit block size.

There's a page on the phpseclib docs, which generates sample code after you input the basic variables (cipher, mode, key size, bit size). It outputs the following for Rijndael, CBC, 256, 256:

<?php
include('Crypt/Rijndael.php');
include('Crypt/Random.php');

$cipher = new Crypt_Rijndael(); // could use CRYPT_RIJNDAEL_MODE_CBC
$cipher->setBlockLength(256);
// keys are null-padded to the closest valid size
// longer than the longest key and it's truncated
//$cipher->setKeyLength(256);
$cipher->setKey('abcdefghijklmnopqrstuvwxyz123456');
// the IV defaults to all-NULLs if not explicitly defined
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));

$size = 10 * 1024;
$plaintext = str_repeat('a', $size);

echo $cipher->decrypt($cipher->encrypt($plaintext));

I am not sure if the library actually supports this cipher without mcrypt availablity, but it should.


I assume you are doing this because mcrypt is being dropped from PHP, and I strongly suggest that you change your strategy.

Even if the above works, it would be quite slow when using a userland PHP implementation of the algorithm (something which is noted in the phpseclib docs), but more importantly - you'll have no other alternatives if this library stops working, is no longer maintained, etc. Non-AES variations of Rijndael are not ubiquitous, and there are more modern algorithms available today anyway (hint: libsodium being added to PHP 7.2).

If I were you, I'd change the algorithm entirely. Of course, that would mean re-encrypting all of the data, but you'll have to do that eventually and now is really the best time to do it.

Upvotes: 1

Related Questions