AesManaged ломает реализацию под Mono ...? - PullRequest
1 голос
/ 13 октября 2011

У меня есть программа, которая в Windows и .NET Framework 4 работает превосходно, однако в Mono (встроенной в MonoDevelop 2.6) функции Encrypt() и Decrypt() работают только наполовину ...

До того момента, когда я локально зашифрую что-то, а затем сразу же расшифрую (под Mono), первые 10 или около того символов сообщения будут зашифрованы, но все, что следует за этим, выглядит совершенно корректно!

Функция шифрования выглядит следующим образом:

    public byte[] Encrypt(string plainText)
    {
        DateTime now = DateTime.Now;
        string timeStamp = now.Millisecond.ToString("000") + "." + now.Second.ToString("00") + "." +
            now.Minute.ToString("00") + "." + now.Hour.ToString("00") + Constants.MessageSplitChar;
        plainText = plainText.Insert(0, timeStamp);

        MemoryStream memoryStream = new MemoryStream();

        lock (this.encryptor)
        {
            CryptoStream cryptoStream = new CryptoStream(memoryStream, this.encryptor, CryptoStreamMode.Write);
            StreamWriter writer = new StreamWriter(cryptoStream);
            try
            {
                writer.Write(plainText);
            }
            finally
            {
                writer.Close();
                cryptoStream.Close();
                memoryStream.Close();
            }
        }

        byte[] encryptedMessage = memoryStream.ToArray();
        return this.AppendArrays(BitConverter.GetBytes(encryptedMessage.Length), encryptedMessage);
    }

Функция расшифровки выглядит следующим образом:

    public string Decrypt(byte[] cipherText)
    {
        try
        {
            string plainText = string.Empty;

            MemoryStream memoryStream = new MemoryStream(cipherText);

            lock (this.decryptor)
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, this.decryptor, CryptoStreamMode.Read);
                StreamReader reader = new StreamReader(cryptoStream);

                try
                {
                    plainText = reader.ReadToEnd();
                    plainText = plainText.Substring(plainText.IndexOf("|") + 1);
                    plainText = plainText.TrimEnd("\0".ToCharArray());
                }
                finally
                {
                    reader.Close();
                    cryptoStream.Close();
                    memoryStream.Close();
                }
            }

            return plainText;
        }
        catch (Exception ex)
        {
            CMicroBingoServer.LogManager.Write(ex.ToString(), MessagePriority.Error);
            return "DECRYPTION_FAILED";
        }
    }

Ответы [ 2 ]

3 голосов
/ 13 октября 2011

Ваш код не показывает, как создаются ваши экземпляры decryptor и encryptor.

Это может быть проблемой, потому что если вы повторно используете экземпляр, тогда вы должны проверить ICryptoTransform.CanReuseTransform.Если он возвращает false , вы не можете повторно использовать один и тот же шифратор / расшифровщик и должны создавать новые экземпляры.

Это даже более важно, поскольку Mono и .NET имеют разные значения по умолчанию для некоторых алгоритмов.Но в любом случае пропуск этой проверки означает, что любые изменения в будущей платформе .NET (или через файлы конфигурации, поскольку криптография может быть подключена с использованием CryptoConfig), вероятно, когда-нибудь повредят ваш код.

3 голосов
/ 13 октября 2011

Может быть важно, сколько символов байтов в начале кажутся бессмысленными ... Если первый блок выходит чепухой, но все остальное в порядке, то может быть, что ваш вектор инициализации не веренпри расшифровке.

В наиболее распространенном блочном режиме CBC при дешифровании IV влияет только на дешифрование первого блока данных, поскольку после этого текст шифра, который действует как IV для более поздних блоков.

Вы явно устанавливаете IV для шифрования и дешифрования?Если нет, то я мог бы представить, что эти два поведения ведут себя по-разному при работе с неустановленными IV (например, windows использует все нули, а mono генерирует случайный IV - это приведет к хорошему дешифрованию окон, потому что IV один и тот же, тогда как mono может генерировать два разныхИВ для процесса шифрования и дешифрования.

Я недостаточно хорошо знаю моно, чтобы найти точное решение, но что-то в этом роде кажется вероятным.

...