在Coldfusion中加密,然后在PHP中解密
我在复制PHP与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
$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个人的发现很好,现在在最初的测试中工作得很好,我会在以后做几个测试,但我相信解决方案是一样的。谢谢你的帮助和及时。帮了我很多忙。谢谢你。找到了真正的问题,但很高兴上面的帮助:)