È possibile utilizzare le uscite AES e SHA-256 con gli stessi ingressi per rompere l'un l'altro?

3

Una rappresentazione astratta della mia domanda assomiglia a questa:

byte[] encrypted = AES.Encrypt(bytesToEncrypt, password);
byte[] hash = SHA256.Hash(password);

Se un utente malintenzionato ottiene i valori sia di encrypted sia di hash , ciò conferisce loro un vantaggio che non avrebbero se avessero uno o l'altro solo?

    
posta user875234 09.06.2018 - 20:52
fonte

2 risposte

3

Questo è sicuro se la password è sicura. Ad esempio, 16 byte generati casualmente come password vanno bene, o forse una password strong che è stata eseguita attraverso una buona funzione di derivazione chiave (KDF) come bcrypt, scrypt o argon2 (più lento è il migliore, quindi un utente malintenzionato può solo fare supposizioni a un ritmo lento).

Stai dando maggiori informazioni all'attaccante, quindi è quasi inevitabile che tu dia più informazioni. Ci sono due cose che posso pensare:

  • Interrompi uno, prendi l'altro

    Il tuo schema è rotto se uno qualcuno trova un attacco preimage su SHA2, o qualcuno trova qualche attacco in AES che porta al recupero delle chiavi.

    Se un utente malintenzionato ha solo l'hash e non il contenuto crittografato, non può usare un attacco su AES per rompere il tuo hash (e viceversa).

    Gli attacchi che interrompono completamente AES o SHA2 sono estremamente improbabili, però. Entrambi gli algoritmi sono estremamente ben studiati e il cracking di solito accade prima degradando sostanzialmente un algoritmo. Se uno di questi due si rompe, siamo comunque in grossi problemi.

  • Identificazione di una password corretta indovina

    Quando incrini i tuoi encrypted bytes, un utente malintenzionato otterrà dei rifiuti casuali come output su ogni tentativo errato. Se il tuo input ( bytesToEncrypt ) è anche indistinguibile da casuale (ad esempio se si tratta di un ID di transazione Bitcoin), un utente malintenzionato non saprà mai quando avrà ottenuto la risposta corretta. (Beh, forse potrebbero controllare tutte le transazioni Bitcoin nella cronologia e trovarne una corrispondente ... ma l'idea è arrivata.)

    Ora, invece, possono trovare un input che corrisponde all'hash. Una volta trovato, sanno che la risposta è giusta e possono utilizzarla per decrittografare il messaggio.

    Di solito, tuttavia, è possibile verificare quando una decrittografia è corretta, quindi questo è solo un piccolo vantaggio. E questo presume che la tua password possa essere indovinata in primo luogo.

Come detto, entrambi sono molto improbabili / non fattibili. Se il tuo input password è sicuro, ad es. 16 byte casuali o una password molto strong e KDF.

Quindi il tuo schema è sostanzialmente sicuro, ma è solo una piccola parte di un'applicazione più grande. Se questa è un'applicazione importante, dovresti farla revisionare da un professionista per assicurarti che sia implementata correttamente. (Nota: questo significa pagare qualcuno, non solo chiedere un forum di revisione del codice o qualcosa del genere).

Inoltre, chiami i tuoi input su AES e SHA2 "password", implicando che sia specificato dall'utente. Un KDF non è visibile nel codice che hai pubblicato, quindi hai bisogno di aggiungerlo. Usa un KDF lento, come uno basato su bcrypt, scrypt o argon2.

    
risposta data 09.06.2018 - 23:06
fonte
2

give the attacker an advantage

Dipende. Cosa sta cercando di fare l'attaccante?

Dato che chiami una delle parti di dati coinvolte "password", presumo che l'obiettivo di chi effettua l'attacco sia trovare questa password e il tuo obiettivo è mantenerlo segreto.

Non è chiaro cosa intendi per AES.Encrypt(bytesToEncrypt, password) . Suppongo che intendi che stai utilizzando una delle modalità di crittografia a blocchi standard utilizzando AES come codice a blocchi, con bytesToEncrypt è la chiave e password è il messaggio da crittografare, o forse il contrario. Qui sotto scriverò AES.Encrypt(key, message) dove key è la chiave di crittografia e message è la stringa da cifrare, poiché questo è l'ordine degli argomenti usati praticamente in tutte le API là fuori.

Se si rivela SHA256.Hash(password) , l'utente malintenzionato può trovare la password calcolando SHA256.Hash(p) per molti valori di p finché non ne trovano uno con un hash corrispondente. Possono fare i calcoli stessi o sfruttare i calcoli fatti da altri. Questo potrebbe essere devastante se l'hash è qualcosa come b9f195c5cc7ef6afadbfbc42892ad47d3b24c6bc94bb510c4564a90a14e8b799 , meno se è qualcosa come 3d5cfec95acbabf275d544e138fdfa02ad3945adc681dfa0cec75a127a9ff6aa , ma una minaccia realistica per qualsiasi password che sia memorabile.

Se rilevi AES.Encrypt(key, password) per l'attaccante, l'attaccante può sapere due cose:

  • Sapranno la lunghezza esatta o approssimativa della password, a seconda della modalità di crittografia che hai usato.
  • Se l'autore dell'attacco riesce anche a ottenere bytesToEncrypt , allora conoscerà la password.

Se si desidera calcolare AES.Encrypt(password, message) , si incorre nel problema che ciò non ha realmente senso. Una chiave AES deve essere una stringa di 16 byte, 24 byte o 32 byte. Non sono possibili altre lunghezze di stringa: l'algoritmo non è definito per altre lunghezze di stringa. Se si utilizza una password che ha la lunghezza di byte richiesta, è una pessima idea perché le chiavi dovrebbero essere generate casualmente. Se si utilizza una password composta da caratteri stampabili e con motivi che la rendono memorabile, non si utilizza AES nel modo in cui è stata progettata. Si apre la strada a attacchi con chiave correlata : è possibile imparare cose dalle relazioni tra le chiavi, come "questo la chiave consiste solo di caratteri ASCII "(cioè il bit più significativo di ogni byte è 0). AES ha conosciuto punti deboli contro gli attacchi con chiave correlata, il che non è un problema nella pratica perché nessun protocollo sano di mente coinvolge le chiavi correlate. Tuttavia, usare una password come chiave non è un protocollo sensato. Inoltre, stai ovviamente rivelando qualcosa sulla lunghezza della password e la stai esponendo allo stesso tipo di attacco a forza bruta del caso SHA-256 se è noto message .

Trovare la password attraverso il suo hash e trovare la password attraverso la sua crittografia è praticamente indipendente. AES e SHA-256 sono disegni non correlati. Conoscere la crittografia rivela la dimensione e quindi rende più facile la ricerca di una password con un hash corrispondente, ma solo marginalmente. Conoscere l'hash non aiuta a rompere la crittografia, a meno di trovare effettivamente la password.

Rivelare o la crittografia o l'hash SHA-256 di una password è una pessima idea, poiché ognuna di esse ha evidenti debolezze (una si rompe se la chiave perde, l'altra è vulnerabile alla brutalità attacchi di forza). Le password dovrebbero essere archiviate solo sotto forma di hash lento e salato , e l'hash deve essere tenuto segreto per buona misura.

¹ In teoria non saprebbero se ciò che hanno trovato è la password effettiva o una stringa diversa con lo stesso hash. Tuttavia, non esiste un modo noto per trovare due stringhe con lo stesso hash SHA-256, e richiederebbe una ricerca di forza bruta in esecuzione su tutti i computer attualmente esistenti circa la vita dell'universo per avere una possibilità non trascurabile di trovarne uno .

    
risposta data 10.06.2018 - 01:00
fonte

Leggi altre domande sui tag