2010-09-17 6 views
6

Ich habe etwas C# -Code geerbt und muss es nach PHP portieren. Hier ist sie:Wie unterscheiden sich meine C# - und PHP-Entschlüsselungsmethoden?

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

Mein PHP-Code sieht wie folgt aus:

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

Aber die beiden entschlüsselten Werte nicht gleich sind, und ich kann nicht herausfinden, warum. Ich habe viele ähnliche Fragen hier und anderswo gelesen, aber keiner von ihnen scheint das Problem zu erklären, das ich habe.

Ich würde wirklich jede Hilfe bei der Ermittlung, warum die entschlüsselte PHP-Zeichenfolge nicht mit der entschlüsselten C# -String übereinstimmt.

+0

Echo die MD5-Hashes jeder Version und sehen Sie das Problem ist da oder später. Echo auch die verschiedenen Byte-Arrays aus und spiele den Unterschied. – colithium

+0

Danke. Ich habe das als erstes versucht, aber da ich nicht viel über C# weiß, war ich nicht sehr zuversichtlich was ich tat. Alles schien bis zur Entschlüsselung in Ordnung zu sein, aber ich bin mir nicht 100% ig sicher. Der hashedKey und der strToDecrypt haben die gleichen Längen wie ihre PHP-Entsprechungen und die gleichen druckbaren Zeichen, so dass es ziemlich sicher scheint, dass sie gleich sind. – matthewwithanm

Antwort

2

ich es endlich geschafft, die Antwort in a comment on the Mcrypt page of the PHP manual zu finden:

Wenn 3DES zwischen PHP und C# verwendet wird, ist es, dass es feine Unterschiede sind zu beachten, dass, wenn nicht strikt eingehalten, in ärgerliches Problem encrypt führen/Daten entschlüsseln.

1), Bei Verwendung eines 16-Byte-Schlüssels generiert php und C# eine völlig unterschiedliche Ergebniszeichenfolge. Es scheint, dass ein 24-Byte-Schlüssel erforderlich ist, damit PHP und C# funktionieren.

2), PHP hat keine "Padding" -Option, während C# 3 (?) Hat. Meine Arbeit besteht darin, Nullen, d. H. Chr (0), am Ende der Quellzeichenfolge hinzuzufügen, um die Größe auf 8 zu setzen, während in C# PaddingMode.Zeros erforderlich ist.

3) die Schlüsselgröße muss Zeiten von 8 sein, in PHP, um es für C# arbeiten zu lassen.

Der entscheidende Punkt hier ist # 1. Da der verwendete Schlüssel das Ergebnis von md5 Hashing ist, wird es 16 Bytes sein. Wenn ich stattdessen einen 24-Byte-Schlüssel verwende, um alles zu verschlüsseln (und dann zu entschlüsseln), dann ist alles in bester Ordnung.

Bis jetzt konnte ich keine Erklärung für finden, warum 16-Byte-Schlüssel ein anderes Ergebnis (oder ob es eine Problemumgehung gibt) erzeugen. Wenn Sie irgendwelche Informationen darüber haben, bitte teilen Sie!

0

Der C# -Schlüssel wird in UTF8 codiert, bevor er mit MD5 gehasht wird. PHP entspricht wahrscheinlich nicht?

Der C# -Ausgang ist ebenfalls UTF8-codiert.

Ich bin nicht allzu vertraut mit PHP, aber anscheinend die Funktion wollen Sie ist utf8_encode, so versuchen Sie Ihre PHP-Seite zu diesem Aktualisierung:

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

Jenseits der UTF8-Codierung Unterschied, es ist nicht garantiert (von der Samples, die Sie zur Verfügung gestellt haben), dass str_encrypted base64-kodiert ist, entweder auf der C# - oder der php-Seite.

Am besten nehmen Sie die Empfehlung von Colithium und geben die Eingaben zurück, um sicherzustellen, dass alle Eingabedaten auf Byte-Ebene übereinstimmen.

+0

Ja, ich habe das versucht, aber es hat keinen Einfluss auf die Ausgabe. – matthewwithanm

+0

Es ist fast immer ein Codierungsfehler auf einer Seite. Ist das str_encrypted definitiv base64 auf beiden Seiten kodiert? – PaulG

+0

Ja, ich verwende die exakt gleiche Zeichenfolge, wie in meinem Beispielcode gezeigt. Gleiche Eingabe. – matthewwithanm

2

Vielleicht möchten Sie dieses Forum überprüfen: http://forums.asp.net/t/1498290.aspx Anscheinend hatte jemand letztes Jahr, was genau das gleiche Problem scheint.

Von dieser Seite sieht es aus wie die C# Zeug sollte UTF-7 codiert sein .. Nicht UTF-8.

+0

Ich hatte das gesehen, aber es schien, als ob das utf7-Ding ein Missverständnis darüber war, wie es funktionierte. (In beiden Fällen scheint es nicht zu funktionieren.) – matthewwithanm

Verwandte Themen