Produzione di hash sicuri per rilevare la manipolazione dei dati

0

Ho un'app per Android che si basa internamente su un database SQLite che archivia dati utente crittografati. I dati vengono crittografati utilizzando AES-256, con una chiave generata dall'algoritmo PBKDF2-HMACSHA256. L'applicazione ha la necessità di rilevare la manipolazione dei dati tramite metodi dannosi o non dannosi (ad esempio, danneggiamento dei dati o qualcuno che manomette intenzionalmente il database).

Per quanto posso dire ho due opzioni solide su come generare in modo sicuro un hash per rappresentare questi dati. O posso fare affidamento su un algoritmo HMAC-SHA256 con chiave con la stessa password utilizzata per generare la chiave AES-256 per generare le firme dei dati in ogni riga del database. In alternativa, potrei generare un normale hash SHA-256 dei dati decrittografati memorizzati in memoria prima di ricodificarlo per aggiornare la riga del database. Quindi, in teoria, solo l'utente autenticato con la chiave corretta può decifrare i dati e quindi solo quell'utente può generare questa "firma".

Ecco la mia domanda: usare HMAC-SHA256 causerà complicazioni con esattamente come mantenere la password in modo sicuro come chiave o in qualche modo per sfruttare la chiave SHA-256 come chiave HMAC. In entrambi i casi, sembra non necessariamente doloroso e la complessità è in generale, una novità negativa per i sistemi sicuri. Sarebbe ugualmente sicuro fare affidamento su un normale hash SHA-256 di dati decrittografati come sarebbe utilizzare un algoritmo di hash in stile HMAC? Come in, sono altrettanto difficili / impossibili da falsificare una firma.

    
posta dFrancisco 23.02.2018 - 17:44
fonte

3 risposte

1

Idealmente dovresti utilizzare un algoritmo di crittografia autenticato integrato come AES-GCM, ma dal momento che hai già dati crittografati, vale la pena guardare le opzioni che non richiedono la codifica di tutto.

La composizione più sicura di crittografia e autenticazione è encrypt-then-authenticate . La soluzione candidata per applicare HMAC ai ciphertexts è quindi la migliore. Assicurati tuttavia di includere anche tutto il contesto pertinente nel calcolo HMAC:

  1. Qualunque sia l'IV che stai passando alla crittografia dovrebbe essere parte dell'input al MAC.
  2. Potrebbe anche avere senso includere altri dati contestuali nell'input MAC. Ad esempio, se c'è una chiave naturale nella riga in cui sono archiviati i dati decrittografati, incluso quello nell'input al MAC difende dagli attacchi in cui qualcuno scambia i valori crittografati su record diversi. (Vedi questa mia risposta a una domanda diversa .)

Per derivare la chiave HMAC, hai alcune opzioni:

  1. PBDKF2 supporta la generazione di uscite lunghe, con una lunghezza di output fornita dall'utente. È possibile richiedere un output più lungo e utilizzare la prima parte per la crittografia (avrà lo stesso valore già ottenuto) e i bit aggiuntivi per il MAC. Un grave svantaggio: può raddoppiare il tempo di esecuzione delle derivazioni PBKDF2.
  2. Potresti usare HKDF-HMAC-SHA256 per ricavare sottochiavi dalla chiave che stai derivando da PBKDF2. Idealmente vorrai derivare sia la chiave di crittografia che quella MAC dalla chiave PBKDF2, ma per la compatibilità con le versioni precedenti potresti risparmiare e utilizzare la chiave master PBDKF2 per la crittografia come fai ora e una chiave derivata da HKDF per il MAC . HKDF è un algoritmo molto semplice costruito su HMAC quindi, anche se le tue librerie non ce l'hanno, non dovresti sentirti troppo spaventato per implementarlo. (Se stai alimentando l'output di PBKDF2, hai solo bisogno della funzione di espansione HKDF e puoi saltare l'estratto di HKDF.)
  3. Economico e utilizza la stessa chiave derivata da PBKDF2 sia per AES che per HMAC. L'uso della stessa chiave per entrambi gli scopi è male in linea di principio (come ha sottolineato @Scovetta), ma è probabilmente sicuro in questo contesto eccezionale perché stai crittografando con AES ma autenticandoti con HMAC-SHA256, che sono algoritmi molto diversi . Questo conta un po 'come "vivere al limite", ma ci sono molte più ragioni per sospettare che sia OK piuttosto che sospettare che sia male. (Se d'altra parte il tuo cifrario e MAC erano entrambi basati su AES, o se c'è sempre la possibilità che tu possa passare a un MAC basato su AES in seguito, usare la stessa chiave per entrambi sarebbe molto spaventoso.)

Di questi andrei con # 2. È il principio principale e sono solo alcune chiamate HMAC-SHA256 in più, che già chiami migliaia di volte con PBKDF2.

L'hashing del testo in chiaro non è una buona idea. Il problema più grande è che consente a un utente malintenzionato di provare le ipotesi su quali siano i testi in chiaro: è esattamente lo stesso tipo di attacco delle password spezzate con hash veloci, le GPU possono solo passare attraverso le ipotesi ad alta velocità.

    
risposta data 23.02.2018 - 22:42
fonte
2

Sono disponibili algoritmi che forniscono protezione antimanomissione. AES-GCM è uno di questi algoritmi. Per link

GCM is an authenticated encryption algorithm designed to provide both data authenticity (integrity) and confidentiality.

AES-GCM è disponibile su Android API 26+. link Raccomando di utilizzare un algoritmo su cui è già incorporato un controllo di autenticità per tentare di implementare questo tipo di cose da soli.

    
risposta data 23.02.2018 - 18:39
fonte
0

In primo luogo, cosa stai cercando di proteggere contro? Giri di bit casuali o modifiche intenzionali da parte di un utente malintenzionato? Se è un po 'ribaltamento casuale, allora la crittografia completa del disco di Android potrebbe essere sufficiente per rilevare questo, se abilitato. Se si tratta di un attacco intenzionale, dovresti chiedere se lo stesso attaccante sarebbe in grado di ottenere la stessa chiave e ripetere il MACing della riga correttamente?

Supponendo che hai ancora bisogno di protezione dell'integrità, puoi delegare questo al driver invece di farlo da solo? SQLCipher potrebbe essere una soluzione praticabile e include MAC a livello di pagina per la protezione dell'integrità.

Mentre GCM fornisce l'autenticazione, ci sono alcuni svantaggi che tu dovrebbe essere a conoscenza.

Non si dovrebbe usare la stessa chiave per la crittografia e HMACing. Invece, creare una chiave (in modo sicuro) e quindi derivare sia la crittografia che HMAC da quella. Esistono molti modi per farlo: ad esempio :

x = <encryption key>
enc_key = HMAC-SHA-256(x, 'encryption key')
hmac_key = HMAC-SHA-256(x, 'hmac key')
    
risposta data 23.02.2018 - 19:30
fonte

Leggi altre domande sui tag