Hashing di un file di grandi dimensioni su un sistema incorporato

7

Sto cercando di trovare un modo per verificare l'autenticità di un file che sto scaricando da un server a un sistema incorporato. Sto pensando di usare un hash (preferibilmente SHA256). La mia preoccupazione principale è che la dimensione del file potrebbe essere troppo grande per caricarlo in un buffer e passarlo alla funzione di hashing.

Durante la ricerca online, ho trovato questa risposta ( link ) che parla del calcolo di un hash tree anziché di un hash per l'intero file. È un approccio valido? Qualcuno ha qualche consiglio per farlo in un modo diverso?

    
posta Aravind 12.02.2018 - 22:34
fonte

3 risposte

5

Finché si riceve il file in ordine dall'inizio alla fine, è possibile calcolare l'hash in modo incrementale. Qualsiasi API di crittografia adatta per i sistemi incorporati (e la maggior parte di quelli che non lo sono) consente di calcolare l'hash passando blocchi successivi dell'input. Ogni volta che hai ricevuto un blocco, inserisci l'input nel calcolo dell'hash e aggiungilo a un file. Quando la trasmissione è finita, finalizza il calcolo dell'hash e cancella il file se l'hash è errato.

Si noti che un hash può solo verificare l'integrità di un file, non l'autenticità. Ciò significa che il dispositivo deve conoscere in anticipo il valore hash, quindi è necessario trasmettere l'hash attraverso un altro canale. In genere ciò avviene utilizzando un canale lento ma affidabile per trasmettere l'hash (ad esempio TLS end-to-end a un server trusted) e un canale con maggiore larghezza di banda ma meno sicurezza per il file stesso (ad esempio un meccanismo di trasmissione).

Un albero di hash è utile solo se è necessario essere in grado di verificare parti del file in modo indipendente senza dover recuperare l'intero file. Se stai ricevendo il file in modo sequenziale e completo, non è utile.

    
risposta data 12.02.2018 - 22:57
fonte
1

Praticamente ogni funzione di hash là fuori, e certamente ogni funzione di hash che vale la pena usare (sì, che include SHA-256), può essere usata in streaming. Non è necessario dargli l'intero file da sottoporre a hash in un singolo blocco; al contrario, puoi nutrirlo con il file in piccoli pezzi e ottenere il valore hash finale quando hai finito.

    
risposta data 12.02.2018 - 22:38
fonte
1

I requisiti di memoria per SHA-2 sono indipendenti dalla dimensione del messaggio.

Il modo in cui la maggior parte degli hash crittografici funziona non è esattamente intuitivo. Tutto ciò che è è una funzione che inizia con un valore iniziale e prende un singolo input della sua dimensione di blocco, che permuta il digest. Non esiste uno stato interno per l'hash, e ogni blocco successivo semplifica semplicemente il digest un po 'di più. Un determinato digest, oltre a un determinato blocco di input, genererà sempre lo stesso nuovo digest. Questa è una delle idee alla base della costruzione Merkle-Damgård , che MD5 e Uso SHA-2. L'operazione di hashing su ogni blocco di input è individuale e atomica, senza rispettare l'intero messaggio (anche se il blocco finale padding codifica la lunghezza totale del messaggio sottoposto a hash). L'hashing di un file implica semplicemente di farlo ripetutamente, iniziando con un valore iniziale specificato dallo standard e terminando quando non ci sono più blocchi da sottoporre a hash. Hai solo bisogno di memorizzare tre cose per calcolare un digest SHA-2:

  • Il digest corrente o il valore iniziale. Questa è la dimensione dell'hash.
  • Il prossimo blocco di input (512 bit o 1024 bit, a seconda delle dimensioni dell'hash).
  • Lo stato interno durante l'operazione di hashing, che è la stessa per ogni blocco.

Da FIPS-180-4 § 5.2, il messaggio viene analizzato interrompendolo in singoli blocchi:

5.2    Parsing the message
The message and its padding must be parsed into N m-bit blocks.

5.2.1  SHA-1, SHA-224 and SHA-256
For SHA-1, SHA-224 and SHA-256, the message and its padding are parsed into N
512-bit blocks, M(1), M(2),..., M(N). Since the 512 bits of the input block may be
expressed as sixteen 32-bit words, the first 32 bits of message block i are
denoted M0(i), the next 32 bits are M1(i), and so on up to M15(i).

5.2.2  SHA-334, SHA-512, SHA-512/224 and SHA-512/256
For SHA-384, SHA-512, SHA-512/224 and SHA-512/256, the message and its padding are
parsed into N1024-bit blocks, M(1), M(2),..., M(N). Since the 1024 bits of the input
block may be expressed as sixteen 64-bit words, the first 64 bits of message block
i are denoted M0(i), the next 64 bits are M1(i), and so on up to M15(i).

Per SHA-1, SHA-256 e SHA-512, la dimensione dello stato interno è grande quanto il digest (gli altri hash come SHA-224 e SHA-512/224 sono semplicemente versioni troncate di versioni più grandi, con diversi valori iniziali). Questo significa che, per il tuo caso d'uso con SHA-256, devi solo essere in grado di memorizzare 256 bit (32 byte) di dati per calcolare il digest di dati di qualsiasi dimensione, da 0 bit a 2 64 - 1 bit (questo limite è dovuto al padding utilizzato, che codifica la dimensione del messaggio in un blocco a 64 bit). Varie ottimizzazioni possono aumentare i requisiti di memoria, ma non abbastanza da costituire un problema per un sistema embedded.

Alcune funzioni hash più recenti hanno uno stato interno più grande della loro dimensione di digest di output per evitare attacchi di estensione della lunghezza , dove, senza conoscere m e avendo solo il suo digest, puoi calcolare il digest di m ', dove m' inizia con il contenuto di m . SHA-3 (indipendentemente dalle dimensioni del digest), ad esempio, ha uno stato interno più grande di 1600 bit per impedirlo. Assicura che ogni singola operazione di hashing dipende dallo stato interno, che non viene rivelato alla fine quando viene rilasciato il digest finale.

    
risposta data 13.02.2018 - 04:13
fonte

Leggi altre domande sui tag