Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 3440|Ответ: 1

[Источник] Ошибки декодирования Base64 существуют во всех версиях .NET

[Скопировать ссылку]
Опубликовано 31.07.2023 18:36:01 | | | |
Однажды солнечным утром я сидел перед своим ноутбуком и перестраивал какой-то код на C#. Всё идёт хорошо, и день будет продуктивным. Потом я добавил слишком много знаков равенства в постоянный литерал строки, и всё взорвалось. Продуктивность исчезла. Воскресная спокойная реконструкция позади. Даже солнце решило спрятаться за облаками.

Потратив 30–40 минут, пытаясь понять, что я делаю не так, я понял, что дело не во мне. Это Microsoft. Похоже, я наткнулся на старый баг в функции декодирования Base64.Convert.fromBase64StringЭтот баг определённо существует с момента появления .NET 1.1 в 2003 году. Ой! Это уже старо. И воспроизвести их несложно. Молодец:

Технически, это незаконная Base64. Юридическая версия — «abc=». Обратите внимание, что только один заполнительный символ =. Кодирование Base64 представляет каждые 6 бит бинарного входа в одном ASCII-символе. Это означает, что каждые 4 символа в строке, закодированной Base64, представляют собой 3 байта. Если закодированные данные не кратны 3 байтам, кодировщик Base64 добавляет заполняющий символ, чтобы Base64 становился кратным 4 символам. Это сгенерирует строку Base64, которая правильно заполняется "abc=". Добавление ещё одного = аннулирует его.

Base64 «abc=» декодируется в виде двух байт [105, 183]. Это правильно. Добавление ещё одного символа заполнения в конце не должно сильно менять закодированное значение. Это как добавить пробел в конце предложения. Да, оно есть, но это не меняет смысл предложения. Но .NET так не считает. «abc==» декодируется в виде байта [109]. Не только он стал короче, что было странно, потому что мы сделали ввод длиннее. Он также изменился. Первый байт идёт от 105 до 109. И это не было исключением. Добавьте ещё = — и получите исключение. Удивительный!

Код:

Выпуск:

'abc=' -> [105, 183]
'abc==' -> [109]
Удивительно, что никто не замечал этого столько лет. Или её нашли, но не исправили. Base64 очень важен для обмена информацией в сети. Его можно увидеть повсюду. Однако .NET уже много лет не избавляется от неисправного декодера Base64.

Сначала я не мог поверить и начал расследование. Я некоторое время гуглил, но ничего не нашёл. Потом я написал на StackOverflow и тоже особо не повезло. Когда я понял, что происходит, мне даже пришлось отвечать на свои собственные вопросы. После некоторого поиска на GitHub я наткнулся на исправление, сделанное в .NET Core в июле 2018 года. Поэтому последняя версия .NET Core корректно решает эту проблему и выдает исключение:

Необработанное исключение: System.FormatException: Вход не является действительной строкой Base-64, так как содержит не-базовый символ 64, более двух символов заполнения или нелегальный символ среди Наполняющие персонажей.
   at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
   на System.Convert.FromBase64String(String s)
   на Program.DecodeAndPrint (String base64) в ./base64/Program.cs:строке 13
   на Program.Main() в ./base64/Program.cs:строка 8
Им понадобилось около 15 лет, чтобы найти и исправить проблему. Интересно, что никто особо не пытался это исправить. Это произошло, когда они переписали код, чтобы ускорить процесс:

В Convert.FromBase64() есть тонкая ошибка, когда второй нелегально наполненный символ в конце строки вызывает «успех» декодирования за счёт удаления предпоследнего символа.

Мы находимся на . Эта ошибка была случайно исправлена при оптимизации API в NetCore 2.1. Добавьте тесты к ошибкам журнала и убедитесь, что мы не возвращаемся назад.
Итак, эта проблема решена в .NET Core 2.2. Но в текущей последней версии .NET Framework 4.7.2 проблемы всё ещё есть. Похоже, что он сломался и в моно.

Обходной путь в .NET 4.7.2 — заполнить неправильно заполненную строку примерно таким:

Исходный текст:Вход по гиперссылке виден.





Предыдущий:Azure DevOps (viii) Compiles ASP.NET MVC проекты с помощью Pipelines Build
Следующий:В .NET 6 используется новый таймер — PeriodicTimer
 Хозяин| Опубликовано 31.07.2023 18:39:50 |



Кодируемая композиция строк в Base64 (какие символы находятся в Base64)
https://www.itsvse.com/thread-10629-1-1.html


Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com