#c# #.net #encryption #mono #rijndael
#c# #.net #шифрование #mono #rijndael
Вопрос:
У меня есть инструмент шифрования, написанный на C #, который принимает строку в качестве входных данных. Когда я запускаю скомпилированный exe-файл на своем компьютере с Windows, я получаю выходные данные, отличные от тех, которые я получал при запуске на удаленном сервере UNIX с использованием mono.
Вот пример:
Windows:
"encrypt.exe 01/01"
Output:
eR4et6LR9P19BfFnhGwPfA==
Unix:
"mono encrypt.exe 01/01"
Output:
Pa8pJCYBN7 U R705TFq7Q==
Я даже попытался ввести входное значение в скрипт, а затем скомпилировать и запустить его снова, и я получил те же результаты.
Функция decrypt расположена в удаленной веб-службе и использует жестко закодированные значения key и IV (я использую эти значения для шифрования), вывод расшифровки:
Input (String generated on windows):
eR4et6LR9P19BfFnhGwPfA==
Output:
01/01
Input (String generated on Unix):
Pa8pJCYBN7 U R705TFq7Q==
Output:
????1
Это функция шифрования:
string text = args[0];
byte[] clearData = Encoding.Unicode.GetBytes(text);
PasswordDeriveBytes bytes = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
string a = Convert.ToBase64String(Encrypt(clearData, bytes.GetBytes(0x20), bytes.GetBytes(0x10)));
Console.Write(a);
public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
{
MemoryStream stream = new MemoryStream();
Rijndael rijndael = Rijndael.Create();
rijndael.Key = Key;
rijndael.IV = IV;
CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
stream2.Write(clearData, 0, clearData.Length);
stream2.Close();
return stream.ToArray();
}
Это функция дешифрования (я не могу внести в это изменения):
byte[] cipherData = Convert.FromBase64String(encryptedString);
PasswordDeriveBytes bytes2 = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
byte[] buffer2 = Decrypt(cipherData, bytes2.GetBytes(0x20), bytes2.GetBytes(0x10));
string output = Encoding.Unicode.GetString(buffer2);
Console.Write(output);
public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)
{
MemoryStream stream = new MemoryStream();
Rijndael rijndael = Rijndael.Create();
rijndael.Key = Key;
rijndael.IV = IV;
CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
stream2.Write(cipherData, 0, cipherData.Length);
stream2.Close();
return stream.ToArray();
}
Комментарии:
1. Я не вижу отладочного кода, гарантирующего, что функция шифрования
clearData
одинакова на обеих платформах. Вы уверены, что это так? Также я надеюсь, что вы не используете константу IV вне ваших примеров…
Ответ №1:
Проблема в этом вопросе не в том, с чем вы имеете дело, но, глядя на разницу в результатах, кажется, что заполнение вызывало беспокойство, поэтому вы можете захотеть взглянуть на некоторые ответы в этом вопросе, но этот ответ может помочь решить вашу проблему.
http://social.msdn.microsoft.com/forums/en-US/clr/thread/3df8d5aa-ea99-4553-b071-42a2ea406c7f/
Вы сталкиваетесь с этой проблемой, когда КЛЮЧ, IV и ЗАШИФРОВАННЫЕ ДАННЫЕ имеют не все правильные размеры блоков и «схему». Единственный способ избежать этой проблемы — использовать IV и КЛЮЧ, сгенерированный алгоритмом. Вы можете использовать GenerateIV, чтобы получить алгоритм для генерации вам IV. Храните это где-нибудь в безопасном месте, так как вам это понадобится. Затем просто вызовите метод encrypt и передайте данные. Затем алгоритм зашифрует данные и присвоит свойству Key значение вновь сгенерированного ключа. Сохраните это вместе со своими зашифрованными данными. Вот и все, что от нее требуется.
Хотя это устарело, ответ о том, что существуют различные причины различия, но если вы можете расшифровать, то причины различия могут быть действительными, приведен здесь: http://lists.ximian.com/pipermail/mono-list/2006-November/033456.html
Итак, если вы можете зашифровать на одном и расшифровать на другом (вы можете это сделать?), то какая разница, если результаты разные?
Комментарии:
1. Я отправляю зашифрованные данные в веб-службу, которая расшифровывает их и сохраняет в базе данных. Проблема в том, что я не могу изменить функцию decrypt. Ключ и IV жестко закодированы в функции decrypt, поэтому мне нужно использовать указанные ключ и IV при шифровании. Проблема в том, что когда я расшифровываю строку, зашифрованную mono, я получаю???? перед строкой, и это неприемлемо.
2. @user735247 — Возможно ли, что в argv[0] есть некоторый пробел? Возможно, вы захотите использовать String . Trim() для этой строки, чтобы избавиться от любых дополнительных пробелов.
3. Кроме того, при расшифровке используется декодирование base-64 перед расшифровкой?
4. я попытался установить значение внутри кода text =»01/01″ вместо text =argv [0], и у меня все еще та же проблема. Да, я использую Convert.Из Base64String(encryptedString) я добавил функцию дешифрования, используемую веб-службой
Ответ №2:
Возможно, проблема в том, что выходные данные являются unicode, а терминал отображает ascii. Я обычно вижу? вместо неправильно понятых символов Юникода.
Проверьте числовые значения массива байтов и количество.
Ascii вдвое меньше, чем в Unicode, поскольку на каждый символ приходится по два байта.
Комментарии:
1. Декодированная строка в Unix: 98 57 2 57 219 64 199 165 49 0 => ????1 Декодированная строка Windows: 48 0 49 0 47 0 48 0 49 0 => 01/01
Ответ №3:
Вы проверили свою тестовую строку на наличие новых строк? Тестовая строка Windows будет иметь возврат каретки перевод строки, в то время как строка Unix будет иметь только перевод строки.