Un hash firmato rivela informazioni sul messaggio originale?

4

Come parte della crittografia end-to-end per la mia app, sto seguendo la procedura standard di utilizzo di RSA per scambiare la chiave temporanea AES256. Attualmente quando A decide la chiave da inviare a B, la crittografa con la chiave pubblica di B. Tutto ciò sta prendendo parte a una connessione TLS al server. Comunque B è una specie di prendere la chiave della cieca fiducia che provenga da A. Ovviamente, non è come se qualcuno potesse mandare B alla chiave AES256. È necessario accedere prima al server prima che sia disposto a passare i messaggi ad A. Anche la chiave AES256 viene inviata solo durante l'installazione di una sessione tra A e B che B avrebbe dovuto accettare prima. Il server controllerà anche che ci sia un inizio di sessione richiesto tra X e B prima di inviare qualsiasi cosa a B e che è davvero X con cui B vuole fare una sessione. Il punto della fine alla fine è quello di impedire al server di sapere cosa succede tra A e B (anche se è il mio fisico).

Ho pensato che fare in modo che A includesse un hash firmato della chiave per B avrebbe rassicurato B che la chiave proveniva davvero da A. Tuttavia, java in Android non è in grado di crittografare l'hash firmato perché è esattamente 2048 bit ( come previsto). Ci sarebbe qualche pericolo nel trasmettere semplicemente l'hash firmato (Java RSA con SHA512) in bella vista? La mia comprensione è che gli hash sono forzati brutali che a questo punto potresti anche solo forzare il tasto AES.

Modifica: Dal momento che sembra che le persone stiano arrivando al cuore del problema: la crittografia su UDP, ciò che è fatto è fatto. Scriverò come lo sto facendo attualmente. È il mio progetto personale quindi accolgo con favore qualsiasi miglioramento. Non sono emotivamente attaccato al metodo attuale.

(Tutto ciò avviene su una connessione TLS esistente poiché il socket "comando" è TCP)

  • A genera la chiave AES256 usando SecureRandom di java.
  • A ottiene una copia della chiave pubblica di B dal server.
  • A invia una chiave crittografica RSA a B utilizzando Android RSA / NONE / OAEPWithSHA1AndMGF1Padding. Questo è scelto per il padding OAEP che (da quello che ho letto) suona come il metodo migliore per rendere l'input di RSA il più casuale possibile per evitare che l'output abbia determinate caratteristiche basate sull'input.
  • B riceve il messaggio e invia un comando "ok" al server che dice A.

(Il resto avviene su UDP semplice)

  • A invia un messaggio a B utilizzando Android cipher's AES / GCM / NoPadding. GCM è stato scelto perché (da quello che ho letto) è il metodo migliore per "tagliare" i dati in pezzi sicuri. GCM dovrebbe contenere un MAC, quindi presumo che si occupi dell'autenticazione per me. Una nuova istanza di cifratura viene istanziata per ogni blocco di dati. Sto assumendo il cipher.init di Android si occupa della IV (nuova per ogni blocco). Dopo la crittografia. i dati vengono inviati [IV lunghezza; IV; AES256 / Dati GCM]. Da quello che ho letto il IV è come un sale che viene usato per prevenire gli attacchi precalcolati. Normalmente in un database il sale viene memorizzato in testo semplice, quindi in questo caso viene trasmesso in chiaro. (Se non è stato questo crea un problema di regressione infinita.)
  • B esegue l'inverso e invia una risposta ad A usando il metodo sopra descritto.

Una nuova chiave AES256 viene utilizzata per ogni sessione tra i 2 per la segretezza in avanti. In termini di riproduzione, i dati in testo semplice hanno un numero di sequenza. Ho visto errori di decodifica MAC nei log quando si utilizza LTE all'inizio della sessione. Non ho avuto una spiegazione plausibile perché.

    
posta AAccount 18.03.2018 - 03:16
fonte

1 risposta

4

Credo che questo sia un caso del problema XY . Stai tentando di consentire l'autenticazione nello schema del protocollo e ti stai chiedendo come farlo in modo sicuro utilizzando un metodo che implicitamente ritieni necessario. La realtà è che ci sono già molti modi per dimostrare che una determinata chiave è autentica senza inviare un hash della chiave. Ti suggerisco di leggere in come TLS fornisce l'autenticazione senza effettivamente firmare la chiave di sessione stessa. Poiché questo è il tema di un'altra domanda, risponderò specificatamente se l'hash firmato di un messaggio (come una chiave condivisa) rivela o meno qualsiasi informazione sul contenuto del messaggio originale (tl; dr la risposta è no, non lo fa).

La firma di un messaggio comporta il calcolo dell'hash del messaggio e la firma dell'hash. Poiché la firma dipende solo dal valore dell'hash, possiamo tranquillamente ignorare la firma. Non fornisce più informazioni sul messaggio rispetto all'hash stesso. Quindi possiamo attaccare l'hash?

Un attacco che consentirebbe a qualcuno di apprendere informazioni sull'input a una funzione di hash data solo il digest stesso è chiamato un (primo) attacco di pre-immagine. Più specificamente, questo è un attacco contro qualche funzione di hash f dove viene fornito solo digest h , si è in grado di trovare un messaggio m arbitrario tale che f (m) = h più veloce della ricerca completa. Tutti i moderni hash crittografici * , come SHA-512, sono congetturati per essere pre-resistenti. Pertanto, fornire l'hash a un messaggio non fornisce informazioni sul messaggio stesso. L'unico modo possibile in cui un utente malintenzionato può trovare il messaggio è se è sufficientemente breve da rendere possibile forzare il messaggio finché non viene trovato un hash corrispondente.

Per riferimento futuro, ci sono tre classi di attacchi contro una funzione hash crittografica f :

  • Attacco preimage - Dato h dove f (m) = h , trova qualsiasi m ' tale che f (m ') = h .

  • 2 ° attacco preimage - Dato m , trova qualsiasi m ' tale che m ≠ m' e f (m) = f (m ') .

  • Attacco collisione : trova qualsiasi coppia di m e m ' tale che m ≠ m' e f (m) = f (m ') .

Si presume che un hash crittografico non interrotto con una lunghezza di digest n abbia una resistenza di preimage e secondo preimage di 2 n e una resistenza di collisione di 2 n / 2 . Questo è il caso di SHA-512.

* Formalmente, un hash crittografico a prova di collisione e preimage è definito come una funzione che associa un input di lunghezza arbitraria a un output a lunghezza fissa. Per uno spazio messaggi di {0,1} * e alcuni n fissi, l'algoritmo per la funzione hash crittografica f è definito come {0, 1} * → {0,1} n . Questo è spiegato più dettagliatamente in una risposta su Crypto.SE .

    
risposta data 18.03.2018 - 03:29
fonte

Leggi altre domande sui tag