Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 3440|Răspunde: 1

[Sursă] Erorile de decodare Base64 există în toate versiunile de .NET

[Copiază linkul]
Postat pe 31.07.2023 18:36:01 | | | |
Într-o dimineață însorită, stăteam în fața laptopului meu și restructuram niște cod C#. Totul merge bine și va fi o zi productivă. Apoi am adăugat prea multe semne egale la șirul constant literal și lucrurile au explodat. Productivitatea a dispărut. Reconstrucția calmă de duminică a rămas în urmă. Chiar și soarele a decis să se ascundă în spatele norilor.

După ce am petrecut 30-40 de minute încercând să-mi dau seama ce greșesc, mi-am dat seama că nu era vina mea. E Microsoft. Se pare că am dat peste un bug vechi în funcția de decodare Base64.Convert.FromBase64StringAcest bug există cu siguranță încă de la introducerea .NET 1.1 în 2003. Wow! Asta e vechi. Și nu este foarte greu de reprodus. Bună treabă:

Din punct de vedere tehnic, asta e ilegal, Base64. Versiunea legală este "abc=". Observați că doar un caracter de umplutură =. Codificarea Base64 reprezintă fiecare 6 biți de intrare binară într-un caracter ASCII. Aceasta înseamnă că fiecare 4 caractere dintr-un șir codificat în Base64 reprezintă 3 octeți. Când datele codificate nu sunt un multiplu de 3 octeți, encoderul Base64 adaugă un caracter de umplutură pentru a face ca Base64 să fie un multiplu de 4 caractere. Aceasta va genera un șir Base64 care este completat corect cu "abc=". Adăugarea altei = îl va invalida.

Base64 "abc=" este decodat ca doi octeți [105, 183]. Așa este. Adăugarea unui alt caracter de umplutură la final nu ar trebui să schimbe cu adevărat valoarea codificată. E ca și cum ai adăuga un spațiu la finalul unei propoziții. Da, este acolo, dar nu schimbă sensul propoziției. Dar .NET nu crede asta. "abc==" este decodat ca un octet [109]. Nu doar că a devenit mai scurt, ceea ce a fost ciudat pentru că am făcut inputul mai lung. De asemenea, a devenit diferit. Primul octet merge de la 105 la 109. Și nici nu a făcut o excepție. Adaugă încă un = și obții o excepție. Uimitor!

Cod:

Ieşire:

'abc=' -> [105, 183]
'abc==' -> [109]
Este cu adevărat uimitor că nimeni nu a observat asta de atâția ani. Sau a fost găsit, dar nu a fost reparat. Base64 este foarte important în schimbul de informații pe rețea. Se poate vedea peste tot. Totuși, .NET nu a eliminat decodorul Base64 defect de ani de zile.

La început nu-mi venea să cred și am început să investighez. Am căutat pe Google o vreme și nu am găsit prea multe. Apoi am postat pe StackOverflow și nici eu nu am avut prea mult noroc. Odată ce am înțeles ce se întâmplă, a trebuit chiar să-mi răspund singur la întrebări. După ce am căutat o vreme pe GitHub, am dat peste o soluție făcută în .NET Core în iulie 2018. Deci cea mai recentă versiune .NET Core gestionează corect această problemă și face o excepție:

Excepție negestionată: System.FormatException: Intrarea nu este un șir valid Base-64 deoarece conține un caracter non-base 64, mai mult de două caractere de umplutură sau un caracter ilegal printre Personaje umplute.
   la System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
   la System.Convert.FromBase64String(String s)
   la Program.DecodeAndPrint(String base64) în ./base64/Program.cs:line 13
   la Program.Main() în ./base64/Program.cs:linia 8
Le-a luat cam 15 ani să găsească și să rezolve problema. Interesant este că nimeni nu a încercat cu adevărat să o repare în mod specific. Acest lucru s-a întâmplat când au rescris codul pentru a-l face mai rapid:

Convert.FromBase64() are un bug subtil în care al doilea caracter umplut ilegal la finalul șirului face ca decodarea să "reușească" prin eliminarea penultimului caracter.

Suntem la . Această eroare a fost corectată accidental când API-ul a fost optimizat în NetCore 2.1. Adaugă teste la erorile de înregistrare și asigură-te că nu dăm înapoi.
Deci această problemă este rezolvată în .NET Core 2.2. Dar în cea mai recentă versiune a .NET Framework 4.7.2 încă are probleme. Se pare că este stricat și în Mono.

Soluția din .NET 4.7.2 este să reumpli șirul populat incorect cu ceva de genul acesta:

Original:Autentificarea cu hyperlink este vizibilă.





Precedent:Azure DevOps (viii) Compilează ASP.NET proiecte MVC folosind Pipelines Build
Următor:Este folosit un nou cronometru în .NET 6, PeriodicTimer,
 Proprietarul| Postat pe 31.07.2023 18:39:50 |



Compoziția șirurilor codificate în Base64 (ce caractere sunt în Base64)
https://www.itsvse.com/thread-10629-1-1.html


Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com