6

C# コードをいくつか継承したので、それを PHP に移植する必要があります。ここにあります:

string key = "some key";
string strEncrypted = "some encrypted string";

byte[] hashedKey = new MD5CryptoServiceProvider().ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
byte[] strToDecrypt = Convert.FromBase64String(strEncrypted);

TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = hashedKey;
tripleDES.Mode = CipherMode.ECB;

string strDecrypted = UTF8Encoding.UTF8.GetString(tripleDES.CreateDecryptor().TransformFinalBlock(strToDecrypt, 0, strToDecrypt.Length));

私のPHPコードは次のようになります。

$key = 'some key';
$str_encrypted = 'some encrypted string';

$hashed_key = md5($key, TRUE);
$str_to_decrypt = base64_decode($str_encrypted);

// The IV isn't used for ECB, but it prevents a warning.
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB), MCRYPT_RAND); 

$str_decrypted = mcrypt_decrypt(MCRYPT_TRIPLEDES, $hashed_key, $str_to_decrypt, MCRYPT_MODE_ECB, $iv);

しかし、復号化された 2 つの値は同じではなく、その理由がわかりません。ここや他の場所で同様の質問をたくさん読みましたが、私が抱えている問題を説明しているようには見えません。

復号化された PHP 文字列が復号化された C# 文字列と一致しない理由を理解する上で、何か助けていただければ幸いです。

4

3 に答える 3

2

PHPマニュアルのMcryptページのコメントで、ようやく答えを見つけることができました。

PHP と C# の間で 3DES を使用する場合、微妙な違いがあり、厳密に守らないと、データの暗号化/復号化という厄介な問題が発生することに注意してください。

1)、16 バイトのキーを使用する場合、php と c# は合計で異なる結果文字列を生成します。PHP と C# が同様に機能するには、24 バイトのキーが必要なようです。

2)、phpには「パディング」オプションがありませんが、c#には3(?)があります。私の回避策は、null、つまり chr(0) をソース文字列の末尾に追加して、サイズを 8 倍にすることですが、C# では PaddingMode.Zeros が必要です。

3) C# で機能させるには、php でキーのサイズを 8 倍にする必要があります。

ここでのキーポイントは #1 です。使用されるキーは md5 ハッシュの結果であるため、16 バイトになります。代わりに、24 バイトのキーを使用して暗号化 (および復号化) すると、すべてが厄介になります。

これまでのところ、 16 バイトのキーが異なる結果を生成する理由 (または回避策があるかどうか)についての説明を見つけることができませんでした。それについて何か情報をお持ちでしたら、共有してください!

于 2010-09-23T20:33:08.350 に答える
2

次のフォーラムを参照してください: http://forums.asp.net/t/1498290.aspx どうやら昨年、まったく同じ問題を抱えている人がいたようです。

そのサイトから、C#のものはUTF-7でエンコードする必要があるようです..UTF-8ではありません。

于 2010-09-17T22:47:43.313 に答える
0

C# キーは、MD5 でハッシュされる前に UTF8 でエンコードされます。PHPの同等物はおそらくそうではありませんか?

C# の出力も UTF8 でエンコードされています。

私は PHP にあまり詳しくありませんが、どうやら必要な関数はutf8_encodeであるため、PHP 側を次のように更新してみてください。

$key = 'some key';
$str_encrypted = 'some encrypted string';

$hashed_key = md5(utf8_encode($key), TRUE);
$str_to_decrypt = base64_decode($str_encrypted);

// The IV isn't used for ECB, but it prevents a warning.
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB), MCRYPT_RAND); 

$str_decrypted = utf8_encode(mcrypt_decrypt(MCRYPT_TRIPLEDES, $hashed_key, $str_to_decrypt, MCRYPT_MODE_ECB, $iv))

str_encryptedUTF8エンコーディングの違いを超えて、c#またはphp側でbase64でエンコードされていることは(提供されたサンプルから)保証されていません。

すべての入力データがバイト レベルで一致することを確認するために、colthium のアドバイスを受けて入力をエコーアウトするのが最善です。

于 2010-09-17T22:45:31.597 に答える