Formato comune per l'invio di dati crittografati + IV?

3

Ho un'app che riceve dati da terze parti utilizzando vari protocolli: MQTT, HTTP, AMQP, ...
Alcuni client non possono utilizzare TLS (dispositivi iot senza supporto TLS), quindi dobbiamo trovare un modo semplice e compatto per ricevere dati crittografati.

La mia idea è di usare un algoritmo simmetrico (AES256 o simile), ma come posso formalizzare la trasmissione dei dati?

Insieme ai dati crittografati, dobbiamo anche passare un InitializationVector . Esiste un formato "contenitore" comune che spiega come dovresti impacchettare encryptedData + IV ?

Ovviamente possiamo semplicemente creare il nostro formato, magari usando ASN.1 o qualche altro formato di serializzazione, ma se qualcosa esiste sarà più facile da spiegare a tutti gli sviluppatori.

Aggiorna
Può Sintassi dei messaggi crittografici (CMS PKCS 7) essere una soluzione valida? O è troppo complesso da implementare su piccoli dispositivi iot?

UPDATE 2 Come sottolineato da @AndrolGenhald, non ho bisogno di passare il sale se immagazzino la chiave all'interno del dispositivo. Ho rimosso il requisito di sale.

UPDATE 3 Sappiamo che l'utilizzo di TLS è la soluzione migliore e infatti per la maggior parte dei dispositivi possiamo utilizzarlo. Sfortunatamente alcuni sviluppatori di terze parti mi dicono che non hanno TLS su un tipo di dispositivo. Non conosco esattamente il dettaglio (probabilmente dovrei investigare meglio ...). Ci chiedono di fornire un modo per inviare dati crittografati senza TLS.

    
posta Davide Icardi 28.07.2018 - 11:16
fonte

4 risposte

2

Per rispondere alla domanda su come impacchettare il testo cifrato e IV, la concatenazione dovrebbe essere sufficiente: IV || ciphertext || tag . Questo formato è utile perché consente lo streaming di crittografia. Genera e invia l'IV, trasmetti in streaming la crittografia, quindi calcola e invia il tag di autenticazione (l'output di decrittografia non può essere trasmesso in streaming, tuttavia, come prima cosa deve essere controllato il tag).

Il lato negativo è che rende più difficile cambiare l'algoritmo o supportare più algoritmi. Potresti includere un identificatore di algoritmo non criptato, ma dovresti essere molto attento, in quanto un utente malintenzionato potrebbe cambiarlo in qualunque cosa desideri, aprendo la porta a attacchi di downgrade .

Ma tu vuoi farlo con una chiave pre-condivisa come alternativa a TLS, quindi c'è molto di più. TLS non fornisce solo riservatezza, ma gestisce anche la gestione delle chiavi e l'autenticità (tra le altre cose). Il problema con una chiave pre-condivisa è che devi essere molto consapevole dei vincoli. RFC 4107 vale la pena leggere.

Nonce / IV Riutilizzo

ChaCha20-Poly1305 e AES-GCM usano entrambi un nonce a 96 bit, il che significa che c'è una probabilità del 50% di ripetere dopo 2 48 messaggi quando si usano nonce casuali, quindi la chiave dovrebbe essere cambiata bene prima di questo ( NIST dice prima di 2 32 messaggi per GCM ). È anche possibile utilizzare un contatore invece di un IV casuale per determinati algoritmi, ma ci sono anche difficoltà con questo. A causa di questo rischio, le RFC per ChaCha20-Poly1305 e AES-GCM utilizzato in CMS entrambi richiedono che venga utilizzato un sistema di gestione delle chiavi automatizzato.

Il sistema di gestione delle chiavi più semplice è rappresentato dalle chiavi di crittografia a chiave simmetrica. Una chiave di contenuto viene generata casualmente per ciascun messaggio e utilizzata per crittografarla e una chiave pre-condivisa viene utilizzata per crittografare la chiave del contenuto da inviare insieme al messaggio.

Salt

La tua domanda menziona un salt, il che implica che stai usando una password. Questa è una cattiva idea . Per ricavare una chiave da una password è necessario un KDF lento come Argon2, bcrypt o PBKDF2, e un dispositivo vincolato probabilmente non è abbastanza veloce per eseguire tale KDF con un costo abbastanza alto da essere sicuro. Sarebbe molto meglio generare la chiave precondivisa con almeno 128 bit di entropia. Confondendo anche tu vuoi trasmettere il sale, il che implica che la password sta cambiando, ma questo contraddice il tuo commento che hai messo una "chiave" sul dispositivo.

L'autenticità

TLS fornisce l'autenticità, che è importante perché le modalità di crittografia comunemente utilizzate come CBC e CTR sono malleabili . È consigliabile utilizzare una modalità AEAD come ChaCha20-Poly1305 o AES-GCM o, in caso contrario, utilizzare un HMAC con Encrypt-Then-MAC.

Dispositivi vincolati

Su dispositivi vincolati che non sono in grado di generare casualità crittograficamente sicura (e quindi non possono generare una chiave nonce / IV o una chiave per messaggio casuale), una chiave precondivisa con un contatore nonce memorizzato potrebbe essere la migliore tu puoi fare. Devi solo essere molto attento a garantire che il riutilizzo di nonce sia impedito anche quando il dispositivo viene spento e riacceso il più facilmente possibile per cambiare la chiave se / quando necessario.

    
risposta data 31.07.2018 - 17:34
fonte
1

Come al solito, probabilmente non è una buona idea eseguire il proprio algoritmo crittografico (e questo include il formato di trasmissione). Consiglierei di utilizzare il formato OpenPGP, che ha standardizzato la trasmissione del vettore di inizializzazione, il seed per la derivazione della chiave dalla passphrase, il testo cifrato stesso, ecc.

Puoi installare gpg e usarlo da una riga di comando (vedi ad esempio qui ), e / o usare BouncyCastle's implementazione. Ci sono alcune domande su BouncyCastle e GPG su SE, vedi ad esempio questo che copre specificamente l'interoperabilità Java / GPG. C'è anche un semplice byte[] decryptor / encryptor servizio implementato negli esempi di BouncyCastle che può servire come punto di partenza.

    
risposta data 31.07.2018 - 12:49
fonte
0

My idea is to use a symmetric algorithm (AES256 or similar), but how can I formalize how data are trasmitted?

AES256 è un ottimo algoritmo simmetrico da utilizzare. Tuttavia, devi anche scegliere una modalità e usarla correttamente. Ti suggerirei di utilizzare una modalità di crittografia autenticata di AES (come GCM), nel qual caso la crittografia è integrata con un MAC (come GMAC in GCM). Una modalità di crittografia autenticata esegue sia la codifica che la codifica di integrità (tramite il MAC) per i tuoi dati, in modo che non solo siano tenuti segreti, ma non possano essere modificati senza che tu te ne accorga.

Along with encrypted data we need also to pass an InitializationVector. There is a common "container" format that explain how you should package encryptedData+IV?

È necessario creare una nuova IV casuale ogni volta che si crittografa i dati. La IV è semplice concatenata all'inizio o alla fine dell'output del testo cifrato della crittografia AE. Non è richiesto alcun contenitore specifico, di per sé, basta inviare IV+ciphertext (il tag MAC è implicito nell'output del testo cifrato della modalità AE) o inviare ciphertext+IV , non ha molta importanza.

Ciò che importa è che hai un modo sicuro per memorizzare le chiavi di crittografia sul dispositivo e che generi una nuova IV casuale ogni volta che crittografate i dati da inviare.

Nel sistema che hai descritto (dove non puoi usare TLS) probabilmente dovrai distribuire chiavi simmetriche segrete con gli endpoint e tenerli al sicuro. Questa sarà la parte difficile del tuo problema. Se hai TLS, non devi preoccuparti di questo perché hai solo bisogno della chiave pubblica del server, che non deve essere tenuta al sicuro su tutti i dispositivi al mondo.

    
risposta data 01.08.2018 - 03:20
fonte
0

Nei commenti dici che non ci sono restrizioni software. Il mio consiglio è di includere la libreria OpenSSL - o una libreria di crittografia simile - all'interno del vostro software e lasciare che gestisca il canale TLS, non è necessario eseguire il rollover del proprio schema di crittografia

Inoltre, l'utilizzo di AES per la crittografia simmetrica lascia il problema di come scambiare le chiavi simmetriche per quella crittografia. Hardcoding è un cattivo consiglio e fare uno schema di scambio chiave deriva dall'implementazione di TLS o dal rollover, in entrambi i casi è un cattivo consiglio anche

    
risposta data 01.08.2018 - 04:12
fonte

Leggi altre domande sui tag