PHP ColdFusion9 AES加密 - 结果不同

use*_*120 2 php encryption coldfusion aes

PHP和ColdFusion9中的AES加密产生了不同的结果.有人可以帮帮我吗?

以下PHP代码

$key = "12345678123456781234567812345678";
$iv = "1234567812345678";
$data = "This is a plain string.";

echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv));
Run Code Online (Sandbox Code Playgroud)

给我G + tdEOfQTtVCQGxW3N5uzkqN207OyfIPxS6zf2xrKKY =

而下面的ColdFusion代码

<cfset thePlainData  = "This is a plain string." />
<cfset theKey    = "12345678123456781234567812345678" />
<cfset theAlgorithm  = "AES/CBC/PKCS5Padding" />
<cfset theEncoding  = "base64" />
<cfset theIV    = "1234567812345678" />

<cfset encryptedString = encrypt(thePlainData, theKey, theAlgorithm, theEncoding, theIV) />
Run Code Online (Sandbox Code Playgroud)

给我KLt55n5/T3ee6xVq9VGFbyCacJznkHEqC/RDRhL + 4nw =

知道我哪里错了吗?提前致谢.

Jus*_*ott 6

不幸的是,ColdFusion和PHP实现之间在使用的明文填充样式方面存在轻微的不兼容性.AES要求明文块大小可被128整除.为此,PHP将使用NULL字符填充明文输入以获得正确的块大小.ColdFusion可以使用Java支持的各种填充技术.不幸的是,ColdFusion和Java支持NULL填充模式,这使得互操作性更加困难.ColdFusion的字符串处理不支持NULL字符,因此您需要在PHP中实现PKCS5Padding架构,以使它们正常运行.

另外,正如评论中所提到的,ColdFusion希望密钥是base64编码的,因此您需要将密钥设置看起来像:

<cfset theKey = toBase64("12345678123456781234567812345678") />
Run Code Online (Sandbox Code Playgroud)

此外,默认情况下Java(和扩展名为ColdFusion)仅支持最大128位的密钥大小.在这里,您使用的是256位密钥,这需要Java Unlimited Strength扩展(对于那些试图测试代码并获得非法密钥大小错误的人).

生成的PHP代码如下所示:

// Function from http://us3.php.net/manual/en/ref.mcrypt.php#69782
function pkcs5_pad ($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

$key = "12345678123456781234567812345678";
$iv = "1234567812345678";
// Pad data with PKCS #5 to prevent PHP from using NULL padding.
$data = pkcs5_pad("This is a plain string.", 16);

echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv));
Run Code Online (Sandbox Code Playgroud)

生成的ColdFusion代码如下所示:

<cfset thePlainData = "This is a plain string." />
<cfset theKey = toBase64("12345678123456781234567812345678") />
<cfset theAlgorithm = "AES/CBC/PKCS5Padding" />
<cfset theEncoding = "base64" />
<cfset theIV = "1234567812345678" />

<cfset encryptedString = encrypt(thePlainData, theKey, theAlgorithm, theEncoding, theIV) />

<cfoutput>#encryptedString#</cfoutput>
Run Code Online (Sandbox Code Playgroud)

两者都输出相同的base64编码字符串:

G+tdEOfQTtVCQGxW3N5uzlu0mGabRKNxuIdAXArQE80=
Run Code Online (Sandbox Code Playgroud)