Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 3440|Відповідь: 1

[Джерело] Помилки декодування Base64 існують у всіх версіях .NET

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

Після 30-40 хвилин, намагаючись зрозуміти, що я роблю не так, я зрозумів, що це не я. Це Microsoft. Схоже, я натрапив на старий баг у функції декодування Base64.Convert.fromBase64StringЦей баг існує з моменту, коли у 2003 році був представлений .NET 1.1. Вау! Це старе. І це не дуже складно відтворити. Гарна робота:

Технічно, це незаконний 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:line 13
   на Program.Main() у ./base64/Program.cs:line 8
Їм знадобилося близько 15 років, щоб знайти і виправити проблему. Цікаво, що ніхто насправді не намагався це виправити спеціально. Це сталося, коли вони переписали код, щоб зробити його швидшим:

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

Ми знаходимося на . Цю помилку було ненавмисно виправлено при оптимізації API у NetCore 2.1. Додайте тести до помилок журналу і переконайтеся, що ми не повертаємося назад.
Цю проблему вирішили в .NET Core 2.2. Але в поточній останній версії .NET Framework 4.7.2 проблеми все ще виникають. Схоже, що він зламаний і в моно.

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

Оригінальний:Вхід за гіперпосиланням видно.





Попередній:Azure DevOps (viii) компілює 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