Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 3440|Odpowiedź: 1

[Źródło] Błędy dekodowania Base64 występują we wszystkich wersjach .NET

[Skopiuj link]
Opublikowano 31.07.2023 18:36:01 | | | |
Pewnego słonecznego poranka siedziałem przed laptopem, restrukturyzując kod w C#. Wszystko idzie dobrze i zapowiada się produktywny dzień. Potem dodałem zbyt wiele równych do dosłownego ciągu stałego i wszystko eksplodowało. Produktywność zniknęła. Niedzielna spokojna odbudowa jest już za nami. Nawet słońce postanowiło schować się za chmurami.

Po spędzeniu 30 do 40 minut próbując zrozumieć, co robię źle, zrozumiałem, że to nie moja wina. To Microsoft. Najwyraźniej natknąłem się na stary błąd w funkcji dekodowania Base64.Convert.FromBase64StringTen błąd zdecydowanie istnieje od czasu wprowadzenia .NET 1.1 w 2003 roku. Wow! To już stare. I nie jest trudno go rozmnażać. Dobra robota:

Technicznie rzecz biorąc, to jest nielegalny Base64. Wersja prawna to "abc=". Zauważ, że tylko jeden znak wypełniacz =. Kodowanie Base64 reprezentuje co 6 bitów binarnego wejścia w jednym znaku ASCII. Oznacza to, że każde 4 znaki w ciągu zakodowanym w Base64 reprezentują 3 bajty. Gdy zakodowane dane nie są wielokrotnością 3 bajtów, enkoder Base64 dodaje znak wypełniający, aby Base64 był wielokrotnością 4 znaków. To wygeneruje ciąg Base64, który jest prawidłowo wypełniony liczbą "abc=". Dodanie kolejnego = unieważni ją.

Base64 "abc=" jest dekodowane jako dwa bajty [105, 183]. Zgadza się. Dodanie kolejnego znaku dosypującego na końcu nie powinno zmieniać zakodowanej wartości. To jak dodanie spacji na końcu zdania. Tak, jest, ale nie zmienia znaczenia zdania. Ale .NET tak nie uważa. "abc==" jest dekodowane jako bajt [109]. Nie tylko się skrócił, co było dziwne, bo wydłużaliśmy wejścia. Stało się też inne. Pierwszy bajt przechodzi z 105 do 109. I nie wyrzucało też wyjątku. Dodaj kolejny = i otrzymasz wyjątek. Zdumiewający!

Kod:

Wyjście:

'abc=' -> [105, 183]
'abc==' -> [109]
To naprawdę niesamowite, że nikt tego nie zauważył przez tyle lat. Albo został znaleziony, ale nie naprawiony. Base64 odgrywa ogromne znaczenie w wymianie informacji w sieci. Można go zobaczyć wszędzie. Jednak .NET od lat nie pozbył się wadliwego dekodera Base64.

Na początku nie mogłem w to uwierzyć i zacząłem to sprawdzać. Szukałem w Google przez jakiś czas i niewiele znalazłem. Potem napisałem na StackOverflow i też nie miałem zbyt wiele szczęścia. Gdy już zrozumiałem, co się dzieje, musiałem nawet sam odpowiadać na swoje pytania. Po dłuższym szukaniu na GitHubie natknąłem się na poprawkę wprowadzoną w .NET Core w lipcu 2018 roku. Najnowsza wersja .NET Core poprawnie radzi sobie z tym problemem i zawiera wyjątek:

Nieobsługiwany wyjątek: System.FormatWyjątek: Wejście nie jest ważnym łańcuchem Base-64, ponieważ zawiera znak niebędący bazą 64, więcej niż dwa znaki dosypujące lub nielegalny znak wśród postacie wypełniające posiłek.
   at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
   at System.Convert.FromBase64String(String s)
   at Program.DecodeAndPrint (String base64) w ./base64/Program.cs:linia 13
   at Program.Main() w ./base64/Program.cs:line 8
Zajęło im około 15 lat, by znaleźć i naprawić problem. Co ciekawe, nikt tak naprawdę nie próbował tego naprawić konkretnie. Stało się tak, gdy przepisali kod, żeby był szybszy:

Convert.FromBase64() ma subtelny błąd, gdzie drugi nielegalnie dopełniony znak na końcu ciągu powoduje "sukces" dekodowania poprzez usunięcie przedostatniego znaku.

Jesteśmy na . Ten błąd został przypadkowo naprawiony, gdy API zostało zoptymalizowane w NetCore 2.1. Dodaj testy, aby rejestrować błędy i upewnij się, że nie cofamy się do końca.
Ten problem został naprawiony w .NET Core 2.2. Jednak w najnowszej wersji .NET Framework 4.7.2 nadal występują problemy. Wygląda na to, że jest zepsute też w mono.

Obejście w .NET 4.7.2 polega na uzupełnieniu błędnie wypełnionego ciągu czymś takim:

Oryginał:Logowanie do linku jest widoczne.





Poprzedni:Azure DevOps (viii) Kompiluje ASP.NET projekty MVC z użyciem Pipelines Build
Następny:Nowy timer w .NET 6, PeriodicTimer, jest używany
 Ziemianin| Opublikowano 31.07.2023 18:39:50 |



Składanie tekstów w Base64 kodowane (jakie znaki znajdują się w Base64)
https://www.itsvse.com/thread-10629-1-1.html


Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com