Ci sono problemi seri con questa tecnica per generare chiavi simmetriche?

4

Sto usando una tecnica presa a prestito da un libro di Bruce Schneier e Niels Ferguson intitolato Crittografia pratica . Fondamentalmente, si riduce a questo:

Bob fa questo:

pubk_A = chiave pubblica di Alice

entropy = byte da PRNG

encrypted_entropy = RSA_Encrypt pubk_A (entropia)

hashed_entropy = SHA2-512 (entropia)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

Bob invia quindi encrypted_entropy ad Alice.

Quindi Alice fa questo:

privk_A = Chiave privata di Alice

entropy = RSA_Decrypt privk_A (encrypted_entropy)

hashed_entropy = SHA2-512 (entropia)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

Funziona alla grande per la generazione di chiavi che possono essere utilizzate per comunicare da Bob ad Alice. Ma ho bisogno di chiavi che posso usare in entrambe le direzioni. Stavo pensando di modificare l'algoritmo in questo modo:

Bob lo fa con entropia:

pubk_B = Chiave pubblica di Bob

hashed_entropy BA = SHA2-512 ( SHA2-256 (pubk_A) || entropia)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

hashed_entropy AB = SHA2-512 ( SHA2-256 (pubk_B) || entropia)

encrypt_key AB = hashed_entropy [0:32]
encrypt_nonce AB = hashed_entropy [32:48]
hmac_key AB = hashed_entropy [48:64]

Alice può fare la stessa cosa dalla sua parte dopo aver ottenuto l'entropia decodificando encrypted_entropy.

Come puoi vedere, ora ci sono due serie di chiavi, una usata per comunicare da Bob ad Alice e un'altra per comunicare da Alice a Bob.

C'è qualcosa di sbagliato in questo? Quali rischi per la sicurezza sto prendendo? La sicurezza del sistema è minore o maggiore di quella che se avessi semplicemente un partito modificato un po 'nel nonce? C'è un modo migliore per gestire questo problema senza aggiungere round trip?

    
posta Omnifarious 28.03.2011 - 19:56
fonte

3 risposte

0

Con RSA è possibile trasmettere in modo sicuro n-1 byte di entropia in base alla dimensione della chiave scelta. Quindi una chiave RSA a 2048 bit può crittografare 2047 bit di dati, che sono più che sufficienti per un paio di key / nonce / hmac. Allungando l'entropia con una funzione di digest del messaggio si dovrebbe essere evitato , tuttavia c'è un'entropia sufficiente ad andare in giro fintanto che il messaggio RSA non viene riempito. Il primo passo è dividere i 2047 bit di entropia a metà e cancellare i risultati:

hashed_entropyA=SHA2-512(entropy[0:1023])
hashed_entropyB=SHA2-512(entropy[1024:2047])

Il primo set:

encrypt_keyB = hashed_entropyB[0:32]
encrypt_nonceB = hashed_entropyB[32:48]
hmac_keyB = hashed_entropyB[48:64]

Il secondo set:

encrypt_keyA = hashed_entropyA[0:32]
encrypt_nonceA = hashed_entropyA[32:48]
hmac_keyA = hashed_entropyA[48:64]

I risultati sono una forma indipendente e strong di derivazione chiave in modo che due parti possano comunicare. Un lato della comunicazione può essere compromesso senza compromettere l'intero sistema. Difesa in profondità, sicurezza nei livelli.

    
risposta data 29.03.2011 - 16:47
fonte
5

Rispondi alla tua domanda specifica: c'è un modo più semplice per modificare il loro schema per ottenere ciò che hai in mente. Vai con quello che c'è nel libro, tranne fare la seguente modifica:

hashed_entropy = SHA2-512(0 || entropy) || SHA2-512(1 || entropy)

così che hashed_entropy ora contiene 128 byte. Ora usa i primi 64 byte per la direzione di Bob- > Alice (ad esempio, estrazione di chiavi e nonce come nel libro), e i successivi 64 byte per la direzione di Alice- > Bob (allo stesso modo, estrazione di chiavi e nonce).

(Qui scrivo || per la concatenazione di due sequenze di byte.)

Nota cautela importante: questo schema non autentica Bob. Non è adatto per l'uso in ambienti in cui è prevista o richiesta l'autenticazione reciproca.

Commento ad alto livello: ho provato a rispondere alla domanda specifica che hai chiesto. Tuttavia, sarei negligente se mi fossi fermato lì. Sei sicuro di fare la domanda giusta? Sei sicuro di aver bisogno di implementare il tuo modo di costruire un canale sicuro (crittografato, autenticato)?

Mentre Crittografia pratica è un libro fantastico, sarei piuttosto riluttante a usare un disegno personalizzato, anche se preso da quel libro, a meno che non avessi altra scelta. Se fossi in me, farei in primo luogo un tentativo serio di riutilizzare un progetto ben progettato e ampiamente distribuito, ad esempio TLS. Solo se questo non riuscisse a soddisfare le mie esigenze, avrei quindi considerato di fare qualcosa di personalizzato.

Le mie critiche non hanno nulla a che fare con la qualità di Crittografia pratica , ma piuttosto con l'ampia varietà di cose che possono andare storte se si progetta e si implementa il proprio canale sicuro (incluso, ad esempio, sottile difetti di implementazione che possono essere introdotti).

    
risposta data 29.03.2011 - 08:30
fonte
1

Ciò che desideri è una funzione di derivazione chiave : un KDF accetta come input una "chiave principale" (qui, stringa "entropia") e produce tanti byte quanti ne occorrono per la crittografia simmetrica. Una singola chiamata di funzione hash è un KDF grezzo che produce tanto output quanto la dimensione dell'output della funzione hash, ovvero 64 byte per SHA-512.

Molti protocolli includono un KDF personalizzato. Ad esempio, in SSL / TLS , la funzione "PRF" (definita nella sezione 5) è una costruzione che utilizza la funzione di hash sottostante (solitamente SHA-256 per TLS 1.2) all'interno di HMAC , ripetutamente. Un altro KDF standard è PBKDF2 (sezione 5.2). In realtà qualsiasi buona cifratura di flusso sarebbe un KDF decente (vedi il progetto eSTREAM per alcuni buoni algoritmi di flusso).

Un'altra opzione potrebbe essere meno dispendiosa con il tuo materiale chiave. Dai nomi che assegni agli elementi derivati ("encrypt_key", "encrypt_nonce", "hmac_key"), suppongo che desideri crittografare simmetricamente le cose, con un controllo di integrità con chiave. La crittografia simmetrica e il MAC insieme non sono un compito facile; ci sono molte insidie nascoste. La cosa intelligente è utilizzare una modalità Autenticata crittografia per un codice a blocchi. Una modalità AE combina la crittografia simmetrica e il controllo dell'integrità e gestisce internamente il proprio KDF. Suggerisco EAX . Tale modalità richiede solo un "nonce": questa è una IV con un solo requisito, cioè non deve essere usato due volte con la stessa chiave. Ciò produrrebbe il seguente protocollo:

  • Bob ottiene alcuni byte M da un PRNG (almeno 16 byte).
  • Bob crittografa M con la chiave pubblica di Alice; Alice userà qui la chiave privata per ottenere M .
  • Sia Alice che Bob calcolano SHA-256 ( M ) producendo una stringa di 32 byte K .
  • Successivamente, Bob invia messaggi ad Alice, usando K [0..15] come chiave con la modalità EAX; il nonce è un contatore di messaggi (1 per il primo messaggio, 2 per il secondo messaggio e così via). Il nonce può essere aggiunto ad ogni messaggio o conosciuto implicitamente da Alice (ad esempio i "messaggi" sono record successivi su una connessione TCP).
  • Allo stesso modo, Alice può inviare messaggi a Bob, usando K [16..31] come chiave con la modalità EAX.

Ed ecco: sono necessari solo 256 bit di materiale chiave iniziale, quindi una semplice invocazione di funzione hash andrà bene; Necessario KDF goffo.

Ma, in realtà, stiamo solo reinventando SSL. Ciò va bene per scopi di ricerca / istruzione, ma, per tutto ciò che è destinato a essere implementato nella pratica, è davvero necessario attenersi ai protocolli standard in cui i problemi di sicurezza e gli ostacoli all'implementazione sono già stati (dolorosamente) ricostituiti. Ho menzionato SSL?

    
risposta data 26.09.2011 - 21:33
fonte

Leggi altre domande sui tag