Я пытаюсь перенести этот код на C # на PHP:
private static string DecryptString(string content, string password) { Rijndael aes; byte[] retVal = null; byte[] contentBytes; byte[] passwordBytes; byte[] ivBytes; try { //Get the content as byte[] contentBytes = Convert.FromBase64String(content); //Create the password and initial vector bytes passwordBytes = new byte[32]; ivBytes = new byte[16]; Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length); Array.Copy(passwordBytes, ivBytes, 16); //Create the cryptograpy object aes = Rijndael.Create(); aes.Key = passwordBytes; aes.IV = ivBytes; aes.Padding = PaddingMode.PKCS7; string mode = aes.Mode.ToString(); //Decrypt retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length); } catch {} return Encoding.Unicode.GetString(retVal); }
Параметр content
– строка длиной 44 символа, кодировка базы 64, параметр password
– строка длиной 6 символов.
Это код PHP, который я собрал:
$content = "[44 char base 64 encoded string]"; $password = "[6 char password]"; $padding = 32 - (strlen($password) % 32); $password .= str_repeat(chr($padding), $padding); $iv = substr($password, 0, 16); $data = base64_decode($content); $decrypted = openssl_decrypt($data, 'AES-256-CBC', $password, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
Результатом кода C # является 10-значное длинное число. Результат PHP – это 32-символьная длинная тарабарщина – я думаю, двоичные данные.
Может ли кто-нибудь помочь мне исправить этот код или у меня есть идея, что я могу попробовать?
Как упоминается zaph в комментариях, этот код не считается очень безопасным, и я советую не использовать его в производственной среде.
При этом здесь есть эквивалент PHP вашего кода на C #:
function DecryptString($content, $password){ $password = mb_convert_encoding($password, "utf-16le"); $padding = 32 - (strlen($password) % 32); $password .= str_repeat("\0", $padding); $iv = substr($password, 0, 16); $data = base64_decode($content); $decrypted = openssl_decrypt($data, 'AES-256-CBC', $password, OPENSSL_RAW_DATA, $iv); $decrypted = mb_convert_encoding($decrypted, "utf-8", "utf-16le"); return $decrypted; }
Тест PHP:
$password = "012345"; $content = "EJWgZ/26wp+Cb5utbM1aMk8XfqPQide4dzjQzzzYfj8="; echo DecryptString($content, $password);
0123456789
Тест C #:
string password = "012345"; string content = "EJWgZ/26wp+Cb5utbM1aMk8XfqPQide4dzjQzzzYfj8="; Console.WriteLine(so.DecryptString(content, password));
0123456789
Заметки:
Строки Unicode для C # кодируются кодировкой Little Endian UTF-16; используйте mb_convert_encoding
для декодирования.
openssl_decrypt
по умолчанию использует дополнение PKCS.
Ключи должны создаваться с помощью функции деривации ключа (используйте Rfc2898DeriveBytes
– hash_pbkdf2
)
IV должны быть случайными байтами (используйте Aes.GenerateIV
– openssl_random_pseudo_bytes
)
Полезные ссылки:
c # совместимые строки Unicode в php
php – mb_convert_encoding
php – openssl_decrypt