Encrypting in Coldfusion and then decrypting in PHP

强颜欢笑 提交于 2019-12-30 18:28:31

问题


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

In PHP encrypting this way:

<?php
    $key = "$224455@";
    $Valor = "TESTE";

    $base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, $Valor, MCRYPT_MODE_ECB)));     
?>

I have the result:

TzwRx5Bxoa0=

In Coldfusion did so:

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

Result:

qOQnhdxiIKs=

What isn't ColdFusion yielding the same value as PHP?

Thank you very much


回答1:


(Too long for comments)

Artjom B. already provided the answer above. Artjom B. wrote

The problem is the padding. The mcrypt extension of PHP only uses ZeroPadding [...] you either need to pad the plaintext in php [...] or use a different cipher in ColdFusion such as "DES/ECB/NoPadding". I recommend the former, because if you use NoPadding, the plaintext must already be a multiple of the block size.

Unfortunately, it is difficult to produce a null character in CF. AFAIK, the only technique that works is to use URLDecode("%00"). If you cannot modify the PHP code as @Artjom B. suggested, you could try using the function below to pad the text in CF. Disclaimer: It is only lightly tested (CF10), but seemed to produce the same result as above.

Update: Since the CF encrypt() function always interprets the plain text input as a UTF-8 string, you can also use charsetEncode(bytes, "utf-8") to create a null character from a single element byte array, ie 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;
}



回答2:


The problem is the padding. The mcrypt extension of PHP only uses ZeroPadding. It means that the plaintext is filled up with 0x00 bytes until the multiple of the block size is reached.

PKCS#5/PKCS#7 padding on the other hand fills it up with bytes that denote the number of bytes missing until the next multiple of the block size. The block size for DES is 8 bytes.

So you either need to pad the plaintext in php (See this drop-in code: A: How to add/remove PKCS7 padding from an AES encrypted string?) or use a different cipher in ColdFusion such as "DES/ECB/NoPadding". I recommend the former, because if you use NoPadding, the plaintext must 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=

Don't forget to unpad the recovered plaintext if you are decrypting in PHP.



来源:https://stackoverflow.com/questions/28915142/encrypting-in-coldfusion-and-then-decrypting-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!