De ce provoacă o parolă defectă "Plăcuța este nevalidă și nu poate fi eliminată"?

Aveam nevoie de o criptare simplă a șirului, așa că am scris următorul cod (cu o mare parte de "inspirație" de la

cod exemplu:

    string password1 = "password";
    string password2 = "letmein";
    string startClearText = "The quick brown fox jumps over the lazy dog";
    string cipherText = encryptString(startClearText, password1);
    string endClearText = decryptString(cipherText, password2);    //exception thrown

Întrebarea mea este, este de așteptat? M-aș fi gândit că decriptarea cu parola greșită ar duce doar la o ieșire nonsensă, mai degrabă decât la o excepție.

0
fr hi bn
Acest lucru mi-a salvat atât de mult timp împreună cu comentariul dvs.: "Codul pare să funcționeze bine, cu excepția faptului că atunci când am decodificat datele cu o cheie incorectă" I jurat dar căutând 2x nu am făcut-o. Sperăm că acest lucru îi ajută pe altcineva înainte de a privi mecanismul de umplere sau schimbarea codului.
adăugat autor atconway, sursa

10 răspunsuri

Am avut o problemă similară, problema în metoda decriptare a fost inițializarea unui flux de memorie gol. când a funcționat atunci când l-am inițializat cu cheia byte cifra de text ca aceasta:

MemoryStream ms = new MemoryStream(cipherText)
0
adăugat

Deși acest lucru a fost deja răspuns, cred că ar fi o idee bună să explicați de ce este de așteptat.

O schemă de umplere este de obicei aplicată deoarece majoritatea filtrelor criptografice nu sunt sigure din punct de vedere semantic și pentru a preveni unele forme de criptoatache. De exemplu, de obicei, în RSA se folosește schema de umplere OAEP care împiedică anumite tipuri de atacuri (cum ar fi un atac plaintext ales sau orbire ).

O schemă de completare adaugă un anumit gunoi la întâmplare la mesajul m înainte de expedierea mesajului. În metoda OAEP, de exemplu, se folosesc două Oracole (aceasta este o explicație simplistă):

  1. Având în vedere dimensiunea modulului pe care l-ați împărțit k1 biți cu biți 0 și k0 cu număr aleator.
  2. Apoi, aplicând o anumită transformare mesajului obțineți mesajul căptușit care este criptat și expediat.

Aceasta vă oferă o randomizare pentru mesaje și o modalitate de a testa dacă mesajul este gunoi sau nu. Întrucât schema de umplere este reversibilă, atunci când decriptați mesajul, în timp ce nu puteți spune nimic despre integritatea mesajului însuși, puteți face, de fapt, o afirmație despre padding și astfel puteți afla dacă mesajul a fost corect decriptat sau faci ceva greșit (de exemplu, cineva a manipulat mesajul sau dacă utilizați cheia greșită)

0
adăugat
Jorge, mulțumesc pentru explicație. Văd același comportament ca cel descris, datele care sunt decriptate sunt corecte. ar trebui să mănânc această excepție sau (sperăm) că există ceva ce fac în mod incorect că pot corecta? ce se întâmplă când excepția este aruncată? toate postările pe care le-am citit par să fie scrise de oameni care sunt mai interesați să facă excepția să dispară. în cazul meu vreau ca utilizarea mea să fie corectă :)
adăugat autor stuck, sursa
@zaph Pur și simplu explic în mod generic de ce obțineți o excepție de tip padding invalid în loc de gunoi atunci când decriptați parola și parola nevalidă. RSA a fost doar un exemplu, schema specifică de umplere folosită fiind și exemplu. Ea răspunde la întrebarea op deoarece spune: Da, este de așteptat și iată de ce și explicația despre acea referință ciudată de "umplutură" pe care o puteți înțelege doar dacă înțelegeți ce este o schemă de umplutură și de ce este folosită, dar vă va permite înșelătoare dacă nu (ceea ce face criptarea are de a face cu padding ???)
adăugat autor Jorge Córdoba, sursa
Aceasta nu răspunde la întrebarea OP, întrebarea se referă la un cifru de bloc simetric Rijndael, nu un cifru asimetric, cum ar fi RSA. Pentru a face ca datele să fie criptate cu un număr mai mare de dimensiune a blocului, se utilizează, în general, PKCS # 7 (nu PKCS # 5). Cu ajutorul acestor scheme de completare, octeții aleatori nu sunt adăugați și nu . Rețineți că ISO 10126 a fost retrasă, iar octeții aleatorii nu au adăugat nicio securitate. Răspunsul ar fi până la punctul în care ar fi vorbit cu paddingul de criptare simetric. Sugestie: rezolvați răspunsul pentru a răspunde la înt
adăugat autor zaph, sursa
Întrebarea este despre Rijndael padding și vă explicați padding RSA care sunt foarte diferite și realizate din diferite motive. OK, înțeleg că oamenii se confundă cu privire la diferența dintre criptarea simetrică și cea asimetrică și că RSA pare să fie mai vizibilă de târziu și mulți oameni folosesc RSA atunci când AES este o potrivire mai bună. Dar ar fi mai bine ca răspunsul să se potrivească întrebării.
adăugat autor zaph, sursa

De asemenea, am primit mesajul Padding este nevalid și nu poate fi eliminat . Așa cum a spus cineva mai sus, cauza a fost un octet tamponat în CryptoStream. Acesta este modul în care a fost rezolvat apelând metoda FlushFinalBlock ():

using (CryptoStream cryptoStream = new CryptoStream(memoryStream, algorithm.CreateDecryptor(), CryptoStreamMode.Write)) {
    cryptoStream.Write(bytes, 0, bytes.Length);
    cryptoStream.FlushFinalBlock();
    result = Encoding.UTF8.GetString(memoryStream.ToArray());
    return result;
}
0
adăugat

Dacă ați eliminat asimetria de taste, pe lângă FlushFinalBlock() (a se vedea răspunsul lui Yaniv), apelând Close() din CryptoStream sunt de asemenea suficiente.

Dacă curățați cu strictețe resursele folosind folosind blocuri , asigurați-vă că ați blocat blocul pentru CryptoStream

using (MemoryStream ms = new MemoryStream())
using (var enc = RijndaelAlg.CreateEncryptor())
{
  using (CryptoStream encStream = new CryptoStream(ms, enc, CryptoStreamMode.Write))
  {
    encStream.Write(bar2, 0, bar2.Length);
  }//implicit close
  byte[] encArray = ms.ToArray();
}

Am fost mușcat de acest lucru (sau similar):

using (MemoryStream ms = new MemoryStream())
using (var enc = RijndaelAlg.CreateEncryptor())
using (CryptoStream encStream = new CryptoStream(ms, enc, CryptoStreamMode.Write))
{
  encStream.Write(bar2, 0, bar2.Length);
  byte[] encArray = ms.ToArray();
}//implicit close -- too late!
0
adăugat
Dar dacă faci encStream.FlushFinalBlock() aș presupune că nu contează unde faci ms.ToArray() (în interiorul sau în interiorul CryptoStream 's folosind ).
adăugat autor nawfal, sursa
OP-ul știe că este o nepotrivire cheie care provoacă eroarea și a întrebat de ce o nepotrivire cheie produce această eroare.
adăugat autor jbtule, sursa

Da, acest lucru este de așteptat, sau cel puțin, exact ce se întâmplă atunci când rutinele noastre de criptare obțin date nedescriptibile

0
adăugat

Pot exista câțiva octeți necitit în CryptoStream. Închiderea înainte de a citi complet fluxul provoca eroarea în programul meu.

0
adăugat

Dacă doriți ca utilizarea dvs. să fie corectă, trebuie să adăugați autentificarea textului dvs. cipher astfel încât să puteți verificați dacă este vorba despre parola corectă sau că textul cifrat nu a fost modificat. Padding-ul pe care îl utilizați ISO10126 va arunca o excepție numai dacă ultima byte nu decripta ca una din cele 16 valori valide pentru padding (0x01-0x10). Deci, aveți o șansă de 1/16 de a nu arunca excepția cu o parolă greșită, unde dacă o autentificați, aveți o modalitate deterministă de a spune dacă decriptarea dvs. este validă.

Utilizarea lui crypto api în timp ce aparent ușor, de fapt este destul de ușor să faci greșeli. De exemplu, folosiți o sare fixă ​​pentru derivarea cheii și a derivatelor iv, ceea ce înseamnă că fiecare text cifrat criptat cu aceeași parolă va reutiliza IV-ul cu acea cheie, care rupe securitatea semantică cu modul CBC, IV trebuie să fie atât imprevizibil și unic pentru o cheie dată.

Din cauza greșelilor ușor de făcut, am un fragment de cod, pe care încerc să-l păstrez revizuit și actualizat (comentarii, probleme binevenite):

Exemple moderne de criptare autentificată simetrică a unui șir C #.

Dacă se utilizează codul AESThenHMAC.AesSimpleDecryptWithPassword (textul cipher, parola) atunci când se utilizează o parolă greșită, se returnează null dacă textul cipher sau iv a fost modificat după criptarea null este returnat, nu veți primi niciodată date junk înapoi sau o excepție de umplutură.

0
adăugat

Am experimentat o simplă "Împingere este invalidă și nu poate fi înlăturată". excepție, dar în cazul meu cheia IV și padding au fost corecte.

S-a dovedit că tot ce lipsea a fost ștergerea fluxului de cripte.

Asa:

            MemoryStream msr3 = new MemoryStream();
            CryptoStream encStream = new CryptoStream(msr3, RijndaelAlg.CreateEncryptor(), CryptoStreamMode.Write);
            encStream.Write(bar2, 0, bar2.Length);
           //unless we flush the stream we would get "Padding is invalid and cannot be removed." exception when decoding
            encStream.FlushFinalBlock();
            byte[] bar3 = msr3.ToArray();
0
adăugat
Același lucru trebuie făcut și pentru encStream.Close (); .
adăugat autor sharpener, sursa
De asemenea, rețineți că un simplu Flush() pe care l-ați face în mod normal cu un flux este nu același cu FlushFinalBlock code> CryptoStream . Acest lucru este puțin ambiguu în descrierea care preced codul.
adăugat autor Marc L., sursa
Acest lucru nu are nicio legătură cu întrebarea, întrebătorul cunoaște cauza excepției, parola rea ​​(nu se înroșește) și întreabă de ce o parolă proastă provoacă această excepție specifică.
adăugat autor jbtule, sursa
Poate ar trebui să utilizați utilizând pe aceste obiecte, deoarece acestea sunt de unică folosință. Ar fi suficient.
adăugat autor user2173353, sursa
Am avut aceeasi problema si FlushFinalBlock a lucrat ca un farmec !!!
adăugat autor Michel Vaz Ramos, sursa

Răspunsul actualizat de utilizator "atconway" a lucrat pentru mine.

Problema nu era cu padding-ul, ci cu cheia care era diferită în timpul criptare și decriptare. Cheia și iv ar trebui să fie aceleași în timpul encriptare și decriptare a aceleiași valori.

0
adăugat

Another reason of the exception might be a race condition between several threads using decryption logic - native implementations of ICryptoTransform are not thread-safe (e.g. SymmetricAlgorithm), so it should be put to exclusive section, e.g. using lock. Please refer here for more details: http://www.make-awesome.com/2011/07/system-security-cryptography-and-thread-safety/

0
adăugat