Encrypt Xojo, Decrypt PHP

Hi,

For years, I have been using a bit of code in Xojo to call a php script that decode it.
Unfortunately, my provide chnged php version, and now old mdecrypt_generic does not wotk anymore…

Here is the Xojo code

'dim a as new AESMBS // 1.7f4
Dim a As AESMBS
a=New AESMBS
Dim key256 As String = TheKey256 // 32 characters
dim iv as MemoryBlock = iv // 16 characters
Dim TheKey256 As MemoryBlock = TheKey256
Call a.SetKey TheKey256, 256// 1.7f4 OK

// PHP pads with NULL bytes if $cleartext is not a multiple of the block size..
while lenb(ClearText) mod 16 <> 0
  ClearText = ClearText + chrb(0)
wend

Dim idata As MemoryBlock = cleartext
dim odata as new MemoryBlock(idata.Size)
dim cipherText as string

a.EncryptCBC idata, idata.Size, iv, odata, 0, 0
cipherText = odata

return EncodingToHexMBS ( cipherText )

Blockquote

Now, in php to decode

function DecryptAHexText ($TheText)
{

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

 if (mcrypt_generic_init($cipher, KEY256, IV) != -1)
	{
		$decrypted = mdecrypt_generic($cipher,hex2bin($TheText));
		mcrypt_generic_deinit($cipher);
		$decrypted = rtrim( $decrypted );
		return $decrypted;
	}
	else
	{
	return '';
	}
}

I know I have to migrate in Php to OpenSSL , but I have tried with any luck…

Would aby one have an idea to traslate mcrypt_generic_deinit to OpenSSL ?

Thanks, Fred

If you want something you can easier decrypt elsewhere, please use CipherMBS class.
We deprecated the AESMBS class because it is not as compatible.

You can use:
https://documentation.xojo.com/api/cryptography/crypto.html.AESEncrypt
And
https://documentation.xojo.com/api/cryptography/crypto.html.AESDecrypt

Those where added in xojo 2021 R3 i believe and seem to be the same as your PHP RIJNDAEL 128 (AES)

Thanks Christian and DerkJ, but I can’t update the app…

What i need is just decoding on the server, with Php…

Convert to (something like this):

// Your function:
Var my_iv As MemoryBlock = iv
Var mykey As String = TheKey256
Var data_unencrypted As MemoryBlock = cleartext
Var data_encrypted  As String = Cryto.AESEncrypt(mykey, data_unencrypted, Crypto.BlockModes.CBC, my_iv)

Var hex_data As String = EncodeHex(data_encrypted)
return hex_data

I believe the padding is automated in xojo, but i’m not sure. Just try the code.

Thanks, DerkJ, but again, I can’t update the app for numerous reasons…

So you want PHP code ?

Ho yes, please, if you can.

Fred

What php version ?

7.2 or 7.3

It worked perfectly with all previous versions of Php, and for more than 10 years…

Something like this:

function DecryptAHexText ($TheText) {
$cipher_algo = "aes-128-cbc";
$TheKey = "your passkey";
$options = OPENSSL_ZERO_PADDING;
$iv = "";
$tag = null
$aad = ""
$result = openssl_decrypt(
    $TheText,
    $cipher_algo,
    $TheKey,
    $options,
    $iv,
    $tag,
    $aad
) ;
return $result;
}

From here:
https://www.php.net/manual/en/function.openssl-decrypt.php

$cipher_alog can be found here:
https://www.php.net/manual/en/function.openssl-get-cipher-methods.php

$options can be OPENSSL_RAW_DATA or OPENSSL_ZERO_PADDING (think you need zero padding)

1 Like

Many Thanks DerkJ,
I’m going to try and will keep you posted.

Many thanks for your help,
Fred

1 Like

Hi @Frédéric_QUOIREZ

Just wondering if you tried it using the Crypto module from Xojo.

No, Javer. The code is Xojo is quite old, but still working perfectly. So no need to change for now.

Hi Guys,

I have tried DerJ’s code without any success.
I have tried different combinaisons :
Algo : aes-128-cbc and aes-128-cbc,
With or without InitVector,

I’m quite sure I have to use the OPENSSL_ZERO_PADDING option, as I add chrb(0) in my Xojo code above.

Concerning the algo to use, I saw here :

that a « aes-256-cbc » should be the way.

Quote at the end of the page :
I believe Mcrypt provides block sizes of 128, 192 and 256 bits. AES only provides the 128 block size. My guess is, MCRYPT_RIJNDAEL_128 is probably referring to Rijndael with 128-bit block size, which is AES. The key size is a different matter, and that is what the 256 denotes in OpenSSL’s AES-256-CBC. If using a Standard Cryptographic Algorithm Name (SCAN), then the Mcrypt algorithm name for the cipher instance would be similar to Rijndael-128(256)/CBC.

Anyway, nothing seems to work.
So, I ‘m still stuck with my php script…

Keeping on searching, I found that
PHP’s AES encryption.

// The first thing to understand is the meaning of these constants:
// MCRYPT_RIJNDAEL_128
// MCRYPT_RIJNDAEL_192
// MCRYPT_RIJNDAEL_256
// You would think that MCRYPT_RIJNDAEL_256 specifies 256-bit encryption,
// but that is wrong.  The three choices specify the block-size to be used
// with Rijndael encryption.  They say nothing about the key size (i.e. strength)
// of the encryption.  (Read further to understand how the strength of the
// AES encryption is set.)
//
// The Rijndael encyrption algorithm is a block cipher.  It operates on discrete 
// blocks of data.  Padding MUST be added such that
// the data to be encrypted has a length that is a multiple of the block size.
// (PHP pads with NULL bytes)
// Thus, if you specify MCRYPT_RIJNDAEL_256, your encrypted output will always
// be a multiple of 32 bytes (i.e. 256 bits).  If you specify MCRYPT_RIJNDAEL_128,
// your encrypted output will always be a multiple of 16 bytes.
//
// Note: Strictly speaking, AES is not precisely Rijndael (although in practice 
// they are used interchangeably) as Rijndael supports a larger range of block 
// and key sizes; AES has a fixed block size of 128 bits and a key size of 
// 128, 192, or 256 bits, whereas Rijndael can be specified with key and block 
// sizes in any multiple of 32 bits, with a minimum of 128 bits and a maximum of 
// 256 bits.
// In summary: If you want to be AES compliant, always choose MCRYPT_RIJNDAEL_128.
//
// So the first step is to create the cipher object:
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

// We're using CBC mode (cipher-block chaining).  Block cipher modes are detailed
// here: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

It does not explain how to decode using OpenSSL, but explain what is done when crypting.

Maybe this will give someone a brillaint idea.

Thanks , Fred

You need:

  • CBC mode (since your MBS code uses that)
  • 256 bits key (32 chars)
  • an IV of 16 characters
  • to note that you get RAW data (unencoded string) converted to hex

Write down what you need and check if these work with it:

Note the Base64 decode/encode and Hex decode/encode that’s important!

Hello and Thanks, Derk,

I saw that link this mornig and already tried it without success…

I agree, in Xojo, I use CBC Mode, a 32 chars key, and a 16 chars iv.
Then , I encode To Hex using EncodingToHexMBS.

This leads to 'AES-128-CBC’ with my key and initvector.

I checked in php the string received and it’s correct. It’s my string coded in hex.
So before trying to Decrypt, I convert it back using hex2bin.

I don’t understand why I would need $raw = base64_decode($TheText); ?
But I tried. Same result, nothing….
openssl_decrypt simply returns a empty string.

I surely miss something, but what ?