TripleDESCryptoServiceProvider - уязвим для отказа в обслуживании?

У нас есть устаревший сайт ASP.NET, который использует здесь методы шифрования:

http://www.codekeep.net/snippets/af1cd375-059a-4175-93d7-25eea2c5c660.aspx

Когда мы вызываем следующий метод, страница загружается очень медленно и в конечном итоге возвращается сброс соединения:

Decrypt(" ", true);

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

Это происходит на сервере Windows 2008 под управлением.NET Framework v3.5.

Я сузил проблему до TransformFinalBlock() вызов.

ПРИМЕЧАНИЕ: на Кассини я не получаю тайм-аут соединения; вместо этого выдается следующее исключение:

System.Security.Cryptography.CryptographicException: Bad Data

Вызов Decrypt() для других строк не вызывает проблем в любой среде.

Почему это происходит? Это ошибка в TripleDESCryptoServiceProvider?

Очевидно, я мог бы отфильтровать cipherString, чтобы отклонить " " и избежать этой конкретной проблемы. Однако меня беспокоит, что некоторые другие значения cipherString, которые я не подозреваю, вызовут DoS.

ОБНОВЛЕНИЕ 2011.06.28

Ниже приведен минимальный код для воспроизведения проблемы:

// problem occurs when toEncryptArray is an empty array {}
      byte[] toEncryptArray = {};

      MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
      byte[] keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes("dummy_key"));
      hashmd5.Clear();

      TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
      tdes.Key = keyArray;
      tdes.Mode = CipherMode.ECB;
      tdes.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tdes.CreateDecryptor();

      // the following line can crashes the ASP.NET Application Pool (may need to call multiple times).
      byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

      tdes.Clear();

2 ответа

Решение

Проблема, как упомянуто выше, состоит в том, что логика дешифрования неправильно обрабатывает случай, когда входной шифр является массивом нулевой длины.

Для этого был создан тикет:

http://connect.microsoft.com/VisualStudio/feedback/details/678150/denial-of-service-in-tripledescryptoserviceprovider

Обратите внимание, что он работает нормально при работе.NET Framework 4.0.

Последний блок - это место, где находится отступ. В вашем примере один пробел - это первый и последний блок. DES/Triple DES - это 64-битный блочный шифр, текст шифра должен быть кратным 8 байтам (64 бита).

У меня нет среды для тестирования, но вы пробовали играть с опциями заполнения? Заполнение с большим количеством пробелов не подойдет, потому что заполнение не будет соответствовать.

Распространенной схемой заполнения является PKCS5. Для одного байта (который зашифрован символом пробела) ваш обычный текст должен быть в шестнадцатеричном виде:

0x?? 0x07 0x07 0x07 0x07 0x07 0x07 0x07

Но в вашем примере кода ожидается ввод base64. Что означает, что ваша входная строка должна быть:

  • Кратное 12 карат
  • Допустимая строка base64

Любая другая строка может быть отклонена.

true значение выглядит как MAC, что означает, что за вашим вводимым простым текстом должен следовать хеш (MD5 в вашем коде). Он поможет вам обнаружить изменения в зашифрованном тексте. Это полезно, когда вы шифруете двоичные данные. Если вы можете легко обнаружить искаженный текст, вы можете установить его в false.

Другие вопросы по тегам