在Coldfusion中加密,然后在PHP中解密

在Coldfusion中加密,然后在PHP中解密,php,encryption,coldfusion,coldfusion-11,Php,Encryption,Coldfusion,Coldfusion 11,我在复制PHP与Coldfusion中生成的相同结果时遇到问题 在PHP中,以这种方式进行加密: <?php $key = "$224455@"; $Valor = "TESTE"; $base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, $Valor, MCRYPT_MODE_ECB))); ?> 我得到的结果是: TzwRx5Bxoa0= 在Coldfusion中: <

我在复制PHP与Coldfusion中生成的相同结果时遇到问题

在PHP中,以这种方式进行加密:

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

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

我得到的结果是:

TzwRx5Bxoa0=

在Coldfusion中:

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

结果:

qOQnhdxiIKs=

什么不是ColdFusion产生与PHP相同的值


非常感谢

问题在于填充。PHP的mcrypt扩展只使用零填充。这意味着明文将填充0x00字节,直到达到块大小的倍数

另一方面,PKCS#5/PKCS#7填充用字节填充,这些字节表示块大小的下一个倍数之前缺少的字节数。DES的块大小为8字节

因此,您要么需要在php中填充纯文本(请参阅此代码中的下拉列表:),要么在ColdFusion中使用不同的密码,例如
“DES/ECB/NoPadding”
。我推荐前者,因为如果使用NoPadding,明文必须是块大小的倍数

$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)));
结果:

qOQnhdxiIKs=

如果您正在用PHP解密,请不要忘记取消加载恢复的明文。

(注释太长)

。Artjom B.写道


问题是填充物。PHP的mcrypt扩展只使用 零填充[…]您需要在php中填充纯文本[…]或 在ColdFusion中使用不同的密码,例如“DES/ECB/NoPadding”。我 建议使用前者,因为如果使用NoPadding,明文必须 已经是块大小的倍数

$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)));
不幸的是,在CF.AFAIK中很难产生一种新的方法,唯一有效的方法是。如果您不能按照@Artjom B.的建议修改PHP代码,您可以尝试使用下面的函数来填充CF中的文本。免责声明:它只是经过了轻微测试(CF10),但似乎产生了与上面相同的结果

更新: 由于使用CF encrypt()函数,还可以使用从单元素字节数组创建空字符,即
charsetEncode(javacast(“byte[]”,[0]),“utf-8”)


示例:

Valor = nullPad("TESTE", 8);
Key = "$224455@";
result = Encrypt(Valor, ToBase64(Key), "DES/ECB/NoPadding", "BASE64");
// Result: TzwRx5Bxoa0=
WriteDump( "Encrypted Text = "& Result ); 
/*
   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;
}
功能:

Valor = nullPad("TESTE", 8);
Key = "$224455@";
result = Encrypt(Valor, ToBase64(Key), "DES/ECB/NoPadding", "BASE64");
// Result: TzwRx5Bxoa0=
WriteDump( "Encrypted Text = "& Result ); 
/*
   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;
}

如果未使用错误Base64对密钥进行编码,则在尝试加密或解密输入字符串时出错:“”无法解码字符串“$224455@”。我发现了问题。我花了足够长的时间。(编辑)@ArtjomB.-如何在php中解码纯文本字符串和键?查阅因此,询问者可能需要根据php函数如何解释值来调整键。@Leigh php使用二进制字符串。因此,输入的编码取决于php文件编码,可能是UTF-8。输出是显式Base64编码的,以匹配ColdFusion编码。我根本不知道ColdFusion为什么需要
ToBase64(Key)
,为什么它会产生与我的答案中的php代码相同的输出。为什么需要ToBase64(Key)我对php不是很熟悉,但CF假设密钥已经是base64编码的(参见上面的链接)。因此,它总是将密钥字符串解码为base64以获取密钥字节。假设与php得到的二进制文件匹配,这可能就是它工作的原因。(编辑)关于padding+1个人的发现很好,现在在最初的测试中工作得很好,我会在以后做几个测试,但我相信解决方案是一样的。谢谢你的帮助和及时。帮了我很多忙。谢谢你。找到了真正的问题,但很高兴上面的帮助:)