Я пытаюсь переписать эту функцию в C #. но выход C # не соответствует php
PHP-версия
// Encrypt data using AES128-cbc function encrypt($data, $key, $iv) { $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', ''); mcrypt_generic_init($cipher, $key, $iv); $multipass = mcrypt_generic($cipher, $data); mcrypt_generic_deinit($cipher); return $multipass; }
Версия C #
public static string encrypt(string encryptionString, string iv, string key) { byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString); var rijn = SymmetricAlgorithm.Create(); rijn.KeySize = 128; rijn.Mode = CipherMode.CBC; var ms = new MemoryStream(); var cs = new CryptoStream(ms, rijn.CreateEncryptor(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv)), CryptoStreamMode.Write); cs.Write(clearTextBytes, 0, clearTextBytes.Length); cs.Close(); var tmp = Encoding.UTF8.GetString(ms.ToArray()); return tmp; }
Шифрование / Расшифровка с помощью PHP:
class Cipher { private $key, $iv; function __construct() { $this->key = "edrtjfjfjlldldld"; $this->iv = "56666852251557009888889955123458"; } function encrypt($text) { $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); $padding = $block - (strlen($text) % $block); $text .= str_repeat(chr($padding), $padding); $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_CBC, $this->iv); return base64_encode($crypttext); } function decrypt($input) { $dectext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, base64_decode($input), MCRYPT_MODE_CBC, $this->iv); return $dectext; } }
Шифрование / Расшифровка с использованием C #:
public class RijndaelSimple { const string iv = "56666852251557009888889955123458"; const string key = "edrtjfjfjlldldld"; static public String EncryptRJ256(string plainText) { var encoding = new UTF8Encoding(); var Key = encoding.GetBytes(key); var IV = encoding.GetBytes(iv); byte[] encrypted; using (var rj = new RijndaelManaged()) { try { rj.Padding = PaddingMode.PKCS7; rj.Mode = CipherMode.CBC; rj.KeySize = 256; rj.BlockSize = 256; rj.Key = Key; rj.IV = IV; var ms = new MemoryStream(); using (var cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write)) { using (var sr = new StreamWriter(cs)) { sr.Write(plainText); sr.Flush(); cs.FlushFinalBlock(); } encrypted = ms.ToArray(); } } finally { rj.Clear(); } } return Convert.ToBase64String(encrypted); } static public String DecryptRJ256(string input) { byte[] cypher = Convert.FromBase64String(input); var sRet = ""; var encoding = new UTF8Encoding(); var Key = encoding.GetBytes(key); var IV = encoding.GetBytes(iv); using (var rj = new RijndaelManaged()) { try { rj.Padding = PaddingMode.PKCS7; rj.Mode = CipherMode.CBC; rj.KeySize = 256; rj.BlockSize = 256; rj.Key = Key; rj.IV = IV; var ms = new MemoryStream(cypher); using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read)) { using (var sr = new StreamReader(cs)) { sRet = sr.ReadLine(); } } } finally { rj.Clear(); } } return sRet; } }
Две проблемы с кодом C #.
Вы не должны кодировать содержимое вашего MemoryStream
в UTF8. Выход CryptoStream
является двоичным и не будет правильно преобразован. Либо верните byte[]
, либо если вы действительно хотите строку, закодируйте вывод на Hex или Base64.
Вам нужно установить режим заполнения через rijn.Padding = PaddingMode.Zeros;
, Хотя это явно не указано, PHP заполняет данные до размера блока, используя 0. По умолчанию для заполнения для SymmetricAlgorithm
является PKCS7.
Также обратите внимание, что подписи ваших методов PHP и C # отличаются. Порядок параметров для вашей функции PHP – это data, key, iv
то время как метод C # – это data, iv, key
. Если у вас все еще есть проблема после изменений, перечисленных выше, возможно, что ваш IV и ключ отменены при вызове вашего метода шифрования на C #.