Rijndael / AES расшифровка C # для преобразования PHP

У меня есть следующий код в C #

string s = "hellowld"; byte[] bytes = new UnicodeEncoding().GetBytes(s); FileStream stream = new FileStream(inputFile, FileMode.Open); RijndaelManaged managed = new RijndaelManaged(); CryptoStream stream2 = new CryptoStream(stream, managed.CreateDecryptor(bytes, bytes), CryptoStreamMode.Read); FileStream stream3 = new FileStream(outputFile, FileMode.Create); try { int num; while ((num = stream2.ReadByte()) != -1) { stream3.WriteByte((byte) num); } [....] 

Этот фрагмент кода расшифровывает определенный файл и выводит расшифрованную версию. В методе CreateDecryptor из RijndaelManaged im используется пароль как KEY, а также как IV.

Я нашел код здесь для stackoverflow для PHP, но если я попытаюсь дать ключ и iv тот же массив байтов, как на C #, ничего не происходит.

 $Pass = "hellowld"; $Clear = file_get_contents('./file.dat', FILE_USE_INCLUDE_PATH); $bytePass=array(); $i = 0; foreach (str_split($Pass) as $value) { $bytePass[$i]=ord($value); $i++; } echo decryptAES($Clear,$bytePass,$bytePass); function decryptAES($content,$iv, $key,$aes) { // Setzt den Algorithmus switch ($aes) { case 128: $rijndael = 'rijndael-128'; break; case 192: $rijndael = 'rijndael-192'; break; default: $rijndael = 'rijndael-256'; } // Setzt den Verschlüsselungsalgorithmus // und setzt den Output Feedback (OFB) Modus $cp = mcrypt_module_open($rijndael, '', 'ofb', ''); // Ermittelt die Anzahl der Bits, welche die Schlüssellänge des Keys festlegen $ks = mcrypt_enc_get_key_size($cp); // Erstellt den Schlüssel, der für die Verschlüsselung genutzt wird $key = substr(md5($key), 0, $ks); // Initialisiert die Verschlüsselung mcrypt_generic_init($cp, $key, $iv); // Entschlüsselt die Daten $decrypted = mdecrypt_generic($cp, $content); // Beendet die Verschlüsselung mcrypt_generic_deinit($cp); // Schließt das Modul mcrypt_module_close($cp); return trim($decrypted); } 

Мне действительно нужна помощь, как правильно создать код в PHP. Не обязательно, чтобы я выводил файл в PHP, строки было бы достаточно.

UPDATE : метод C # RijndaelManaged по умолчанию – AES-128-CBC. Я изменил свой PHP-код на этот модуль mcrypt (по умолчанию метод шифрования C # )

ОБНОВЛЕНИЕ 2: мне удалось создать Java Decryptor, который приведет меня к другому. PHP должен использовать PKCS7 Padding.

Ваш код на C # действительно не выглядит безопасным, поэтому, если вы можете его изменить, см. Ниже некоторые советы. Вот ваш данный PHP-код, который был изменен, чтобы он выглядел так, как будто он был эквивалентен приведенному коду C #.

 function decryptAES128CBC($content,$iv, $key) { // AES is Rijndael-128 $rijndael = 'rijndael-128'; // key size is 128 bit = 16 bytes $ks = 16; // CBC mode, not OFB $cp = mcrypt_module_open($rijndael, '', 'cbc', ''); // pad key and IV by zeros (this is not a good idea) $key = str_pad($key, $ks, "\0"); $iv = str_pad($key, $iv, "\0"); // initialize the decryptor with key and IV mcrypt_generic_init($cp, $key, $iv); // the actual work $decrypted = mdecrypt_generic($cp, $content); // clean up mcrypt_generic_deinit($cp); mcrypt_module_close($cp); // remove padding, see below return unpad($decrypted); } 

Последняя unpad заключается в удалении дополнения, которое, вероятно, было добавлено функцией шифрования, чтобы увеличить размер сообщения до полного количества блоков. По умолчанию используется RijndaelManaged – PKCS7-padding, который добавляет несколько байтов (от 1 до 16), каждый из которых равен количеству добавленных байтов. В реальной реализации вы должны проверить после дешифрования, что заполнение является допустимым (т. Е. Что все эти байты имеют одинаковое значение), но для «быстрого и грязного» вы можете просто использовать что-то, что проверяет последний байт и удаляет много байтов. См. Комментарии к mcrypt_decrypt для примера.

Если вы можете изменить свой код на C #:

  • Обратите внимание, что обычно не рекомендуется использовать фиксированное значение (за ключ) в качестве вектора инициализации, а использование самого ключа как вектора инициализации тоже не является хорошим. Используйте случайный вектор инициализации (отправленный вместе с сообщением) или см. Следующую точку.

  • Кроме того, вы обычно не хотите использовать (достаточно короткий) пароль непосредственно в качестве ключа, но вместо этого используйте более длинную фразу и хешируйте ее солью (включенной в сообщение), чтобы получить ключ. Если вы это сделаете, вы также можете получить вектор инициализации из тех же двух частей данных (но таким образом, чтобы они были разными, используя функцию деривации ключа). Чтобы избежать принудительного ввода пароля из зашифрованного файла, используйте здесь медленную хэш-функцию (PBKDF-2 или bcrypt).