Encryption in Coldfusion and then decryption in PHP

I have a problem reproducing the same result generated in PHP vs Coldfusion.

In PHP, encryption is as follows:

<?php $key = " $224455@ "; $Valor = "TESTE"; $base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, $Valor, MCRYPT_MODE_ECB))); ?> 

I have a result:

TzwRx5Bxoa0 =

In Coldfusion, they did this:

 <cfset Valor = "TESTE"> <cfset Key = " $224455@ "> <cfset base = Encrypt(Valor,ToBase64(Key),"DES/ECB/PKCS5Padding","BASE64")> 

Result:

qOQnhdxiIKs =

What doesn't ColdFusion mean with the same value as PHP?

Many thanks

+7
coldfusion php encryption coldfusion-11
source share
2 answers

(Too long for comments)

Artyom B. has already provided the answer above . Artyom B. wrote

The problem is laying. The mcrypt extension in PHP uses only ZeroPadding [...], which you need to either fill in plain text in php [...] or use another cipher in ColdFusion, such as "DES / ECB / NoPadding". I recommend the first, because if you use NoPadding, the plaintext should be a multiple of the block size.

Unfortunately, it's hard to get the null character in CF. AFAIK, the only method that works is to use URLDecode("%00") . If you cannot change the PHP code as suggested by @Artjom B., you can try using the function below to fill in the text in CF. Disclaimer: It is only slightly tested (CF10), but seems to give the same result as above.

Update : since the CF encrypt () function always interprets plain text input as a UTF-8 string , you can also use charsetEncode (bytes, "utf-8") to create a null character from a byte array from a single element, i.e. charsetEncode( javacast("byte[]", [0]), "utf-8")


Example:

 Valor = nullPad("TESTE", 8); Key = " $224455@ "; result = Encrypt(Valor, ToBase64(Key), "DES/ECB/NoPadding", "BASE64"); // Result: TzwRx5Bxoa0= WriteDump( "Encrypted Text = "& Result ); 

Function:

 /* Pads a string, with null bytes, to a multiple of the given block size @param plainText - string to pad @param blockSize - pad string so it is a multiple of this size @param encoding - charset encoding of text */ string function nullPad( string plainText, numeric blockSize, string encoding="UTF-8") { local.newText = arguments.plainText; local.bytes = charsetDecode(arguments.plainText, arguments.encoding); local.remain = arrayLen( local.bytes ) % arguments.blockSize; if (local.remain neq 0) { local.padSize = arguments.blockSize - local.remain; local.newText &= repeatString( urlDecode("%00"), local.padSize ); } return local.newText; } 
+5
source share

The problem is the addition. The mcrypt extension for PHP uses only ZeroPadding. This means that plaintext is filled with 0x00 bytes until a multiple of the block size is reached.

PKCS # 5 / PKCS # 7, on the other hand, fills it with bytes, which indicate the number of bytes skipped to the next multiple block size. The block size for DES is 8 bytes.

Thus, you either need to fill in the plaintext in php (see this code: A: How to add / remove the PKCS7 add-on from the encrypted AES string? ) Or use another cipher in ColdFusion, for example "DES/ECB/NoPadding" . I recommend the first, because if you use NoPadding, the plaintext should already be a multiple of the block size.

 $key = " $224455@ "; $Valor = "TESTE"; function pkcs7pad($plaintext, $blocksize) { $padsize = $blocksize - (strlen($plaintext) % $blocksize); return $plaintext . str_repeat(chr($padsize), $padsize); } $base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, pkcs7pad($Valor, 8), MCRYPT_MODE_ECB))); 

Result:

qOQnhdxiIKs =

Remember to unpack the recovered plaintext if you decrypt it in PHP.

+5
source share

All Articles