Тази статия е огледална статия за машинен превод, моля, кликнете тук, за да преминете към оригиналната статия.

Изглед: 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 от години.

Първоначално не можех да повярвам и започнах да разследвам. Търсих в Google известно време и не намерих много. После публикувах в 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