Расшифровать строку в C# зашифрованную в PHP (Blowfish)
Я изо всех сил пытаюсь расшифровать некоторые значения в C#, которые зашифрованы в PHP. Шифрование в PHP si осуществляется с помощью следующего:
function encrypt($pure_string, $encryption_key) {
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = 'fÔdñá1f¦';
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
$encrypted_string = base64_encode($encrypted_string);
return $encrypted_string;
}
Поскольку используется режим ЕЦБ IV, вероятно, он не используется, но все равно это не помогает. Самая большая проблема заключается в том, что документация PHP настолько плоха, и она не указывает, какую кодировку используют функции! Передаваемая строка имеет различные значения байтов в зависимости от кодировки, и в конечном итоге шифрование (в данном случае Blowfish) имеет дело с байты.
Не зная кодировки, я просто пробую разные кодировки в своем коде C#, но безуспешно. Где-то я читал, что PHP использует внутреннюю кодировку "iso-8859-1", но даже с этим он не работает.
Удалось ли кому-нибудь расшифровать в C# некоторое значение, которое было зашифровано в PHP с помощью глупой функции mcrypt_encrypt()?
Обновить
Я сделал пример на PHP. Код:
define("ENCRYPTION_KEY", "1234asdf");
define("IV", "1#^ÊÁñÔ0");
$clearText = "abc";
function encrypt($pure_string, $encryption_key, $iv) {
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
$encrypted_string = base64_encode($encrypted_string);
return $encrypted_string;
}
$encrypted_string = encrypt($clearText, ENCRYPTION_KEY, IV);
echo "Key:" . ENCRYPTION_KEY . "<br />";
echo "IV:" . IV . "<br />";
echo "Clear Text:" . $clearText . "<br />";
echo "Encrypted Text:" . $encrypted_string . "<br />";
И в результате получается:
Key:1234asdf
IV:1#^ÊÁñÔ0
Clear Text:abc
Encrypted Text:OiZ6QIdhXYk=
Также Я подтверждено, что IV не используется, любое значение я передаю результат тот же.
2 ответа:
Ну, проблема в вашем случае - это не часть расшифровки blowfish в c#, это часть шифрования в php. И нет, это не об использовании
mcrypt_encrypt
, это ошибка, чтобы вызватьutf8_encode
на уже кодированной строке utf8...Функция расшифровки, которую я создал, использует BouncyCastle. Есть две зашифрованные строки, первая была создана с помощью функции php, которую вы опубликовали, для второй я удалил вызов
utf8_encode
внутриmbcrypt_encrypt
.В первом примере используется (bad) php_utf8_encoded string, нам нужно преобразовать расшифрованный массив байтов назад и вперед, чтобы получить правильный результат.
Отладьте второй вызов функции расшифровки c# и посмотрите на результат первогоstr1
, произведенногоEncoding.UTF8.GetBytes
. Это правильно, без обратного и обратного преобразования кодировки.public static string BlowfishDecrypt(string encrypted, string key) { var cipher = new BufferedBlockCipher(new BlowfishEngine()); var k = new KeyParameter(Encoding.UTF8.GetBytes(key)); cipher.Init(false, k); var input = Convert.FromBase64String(encrypted); var length = cipher.GetOutputSize(input.Length); var block = new byte[length]; var len = cipher.ProcessBytes(input, 0, input.Length, block, 0); var output = cipher.DoFinal(block, len); // dont know how we get the real length of the content here... but this will do it. But I am sure there is a better way... var idx = Array.IndexOf(block, (byte)0); var str1 = Encoding.UTF8.GetString(block, 0, idx); var raw1 = Encoding.GetEncoding("iso-8859-1").GetBytes(str1); var str2 = Encoding.UTF8.GetString(raw1); return str2; } static string original = "@€~>|"; static string encrypted_with_utf8_encode = "7+XyF+QGcA8lz5AQlLf1FA=="; static string encrypted_without = "3oWsAOEF+Kc="; static string key = "t0ps3cr3t"; public static void Main() { var decrypted1 = BlowfishDecrypt(encrypted_with_utf8_encode, key); var decrypted2 = BlowfishDecrypt(encrypted_without, key); var same = original.Equals(decrypted1); Debugger.Break(); }
В конце концов смог это сделать. Несколько указателей:
Некоторые библиотеки Blowfish в C#, похоже, имеют плохую реализацию. Тот, который работал правильно, был https://github.com/b1thunt3r/blowfish-csharp
Никогда не используйте методы, которые непосредственно работают со строками. Это глупо в первую очередь предлагать в любой библиотеке (даже та, что выше, имеет перегрузки, которые работают со строками, и она "предполагает", что строки находятся в Unicode!)
Когда имеешь дело с различные платформы, попробуйте убедить другую сторону использовать кодировку base64.
В конце концов, я удивляюсь, почему так много разработчиков (даже те, кто разрабатывает криптобиблиотеки) не понимают, что работа со строками без указания кодировки глупа и не имеет никакого смысла!