2

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));

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) />

私に KLt55n5/T3ee6xVq9VGFbyCacJznkHEqC/RDRhL+4nw= を与えます

私が間違っている場所はありますか?前もって感謝します。

4

2 に答える 2

6

残念ながら、使用されるプレーンテキスト パディング スタイルに関して、ColdFusion と PHP の実装の間には若干の非互換性があります。AES では、128 で割り切れる平文のブロック サイズが必要です。これを達成するために、PHP は平文の入力を NULL 文字で埋めて、適切なブロック サイズを取得します。ColdFusionでは、Java でサポートされているさまざまなパディング手法を使用できます。残念ながら、ColdFusion も Java も相互運用性をより困難にする NULL パディング スキーマをサポートしています。ColdFusion の文字列処理は NULL 文字をサポートしていないため、適切に相互運用するには、代わりにPHP 内に PKCS5Padding スキーマを実装する必要があります。

また、コメントで述べたように、ColdFusion はキーが base64 でエンコードされていることを想定しているため、キー設定を次のようにする必要があります。

<cfset theKey = toBase64("12345678123456781234567812345678") />

さらに、デフォルトで Java (および拡張子は ColdFusion) は、最大 128 ビットのキー サイズのみをサポートします。ここでは、Java Unlimited Strength 拡張機能が必要な256 ビット キーを使用しています(コードをテストしようとして、不正なキー サイズ エラーが発生した場合)。

結果の 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));

結果の 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>

どちらも base64 でエンコードされた同じ文字列を出力します。

G+tdEOfQTtVCQGxW3N5uzlu0mGabRKNxuIdAXArQE80=
于 2012-04-25T05:35:02.520 に答える