Я дешифрую данные с помощью PHP с этим кодом:
$content="1234";
$cp = mcrypt_module_open('rijndael-128', '', 'cbc', '');
$iv = mcrypt_create_iv(16, MCRYPT_RAND);
$key = pack("H*",md5('a'));
mcrypt_generic_init($cp, $key, $iv);
$encrypted = mcrypt_generic($cp, $content);
echo base64_encode($key)."\n";
echo base64_encode($iv)."\n";
echo base64_encode($encrypted)."\n";
mcrypt_generic_deinit($cp);
mcrypt_module_close($cp);
$iv и $encrypted затем сохраняются в файл и чтение в демонстрационном приложении C#:
var iv=...;
var encrypted=...;
var md5 = new MD5CryptoServiceProvider();
var key = md5.ComputeHash(Encoding.Default.GetBytes("a"));
md5.Clear();
Console.WriteLine(Convert.ToBase64String(key));
Console.WriteLine(Convert.ToBase64String(iv));
Console.WriteLine(Convert.ToBase64String(encrypted));
Вывод здесь является точно тем же как выводом от PHP, таким образом, я могу гарантировать, что нет никакого ошибочного промежутка кодирования.
var rd = new RijndaelManaged {
Key = key,
IV = iv,
Mode = CipherMode.CBC,
KeySize = 128,
Padding = PaddingMode.Zeros
};
var buffer = new byte[encrypted.Length];
using(var ms = new MemoryStream(buffer)) {
using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Write)) {
cs.Write(encrypted, 0, encrypted.Length);
ms.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.Default.GetString(buffer));
}
}
rd.Clear();
Результат дешифрования варьируется на каждой программе, запускаются, даже с точно теми же входными данными:
Первый показ:
DMF1ucDxtqgxw5niaXcmYQ == <-Ключ
GoCeRkrL/EMKNH/BYeLsqQ == <-IV
UBE3DkgbJgj1K/TISugLxA == <-Зашифрованный
OlOB99yiCYRDoLx+0xxZxQ == <-"Дешифрованный"
Второе выполнение:
DMF1ucDxtqgxw5niaXcmYQ == <-Ключ
GoCeRkrL/EMKNH/BYeLsqQ == <-IV
UBE3DkgbJgj1K/TISugLxA == <-Зашифрованный
w5fcY5Fbb9KRgoHfhqAztA == <-"Дешифрованный"
Ключ, IV, Зашифрованные данные идентичны, но тем не менее дешифрованная дата варьируется и является всегда неправильной. буфер должен содержать "1234" или "1234" плюс 12 конечных нулей.
Я не вижу, почему результаты варьируются и что не работает, но я уставился на эту проклятую часть кода в течение нескольких часов теперь и вероятно пропускаю очевидную ошибку...
Инвертирование CryptoStream как это создает тождественно неправильные результаты:
using(var ms = new MemoryStream(encrypted)) {
using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) {
cs.Read(buffer, 0, buffer.Length);
Console.WriteLine(Convert.ToBase64String(buffer));
}
}
Помощь? Спасибо! Alexander
Итак, изменив старый образец моих прошлых грехов, я получил следующее:
static string Decrypt() {
byte[] keyBytes = Convert.FromBase64String("DMF1ucDxtqgxw5niaXcmYQ==");
byte[] iv = Convert.FromBase64String("GoCeRkrL/EMKNH/BYeLsqQ==");
byte[] cipherTextBytes = Convert.FromBase64String("UBE3DkgbJgj1K/TISugLxA==");
var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC, IV = iv, KeySize = 128, Key = keyBytes, Padding = PaddingMode.Zeros};
using (var decryptor = symmetricKey.CreateDecryptor())
using (var ms = new MemoryStream(cipherTextBytes))
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) {
var plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cs.Read(plainTextBytes, 0, plainTextBytes.Length);
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
, который дал "1234" с завершающими символами \ 0. Вы просто забыли снова преобразовать byte [] в строку? Какого еще отличия мне не хватает?