Un modo sicuro per crittografare una connessione tra 2 client che proteggono sia da avversari attivi che passivi

4

Recentemente mi sono interessato alla crittografia e ai metodi dietro di loro. Quindi per un progetto divertente / scolastico sto costruendo un programma in python per crittografare i dati tra due client (chat e file).

Non sono proprio sicuro di come renderlo veramente sicuro contro gli attacchi sia passivi che attivi. In questo momento la mia idea è di usare un server per stabilire un handshake tra i client nel modo seguente:

  1. Una volta avviato, il client si connette al server per comunicarne la presenza.
  2. Client bob consente al server di sapere che desidera connettersi al client Alice
  3. Il server invia un messaggio al client Alice che bob vuole impostare una connessione sicura
  4. Alice dice al server che accetta la connessione
  5. Il server genera un numero casuale e lo crittografa utilizzando la chiave pubblica del client Il client ha una chiave RSA privata codificata (non cambia per connessione / client)
  6. Server invia il numero casuale sia ad Alice che a Bob
  7. Alice e Bob decodificano il numero casuale e lo cancellano, entrambi lo rimandano al server
  8. Il server controlla se entrambi gli hash sono uguali (nessuno è temperato con)
  9. Il server invia un OK o un errore ad entrambe le parti
  10. Alice e bob cancellano il numero un numero di volte uguale al numero casuale (quindi se il server invia 1234 lo cancellano 1234 volte.
  11. Alice e Bob impostano una chiave comune per questa connessione utilizzando lo scambio di chiavi Diffie-Hellman e crittografano lo scambio con AES.
  12. Una volta decisa una chiave comune, utilizzare questa chiave o un hash di questa chiave per la crittografia AES (questa chiave cambia per connessione e tutti i dati vengono inviati su questo canale)

L'unico problema che vedo con questo protocollo se gli avversari possono decodificare il mio codice per ottenere la chiave privata e possono usare attacchi attivi sia con Alice che con la connessione di Bob OPPURE se il server è mai compromesso.

Userò py2exe per compilare il codice, in questo modo dovrebbe essere difficile ottenere la chiave ma non sono sicuro di quanto sarebbe difficile.

Ci scusiamo per la lunga domanda, ma sembra davvero un'idea orribile per codificare la chiave nel client, ma non sono sicuro di dove andare da qui.

Pensieri su questa idea / miglioramenti / Come posso fare meglio?

Ci scusiamo per qualsiasi refuso, l'inglese non è la mia prima lingua.

    
posta Alfuananzo 18.12.2014 - 17:48
fonte

5 risposte

1

Non è possibile avere una chiave privata codificata nel software distribuito.

Le due opzioni che vedo sono:

  1. Chiedi a ogni cliente di generare una coppia di chiavi univoche che usano per comunicare con il server. Bob invierà la sua chiave pubblica al server quando si connetterà inizialmente. Il server crittograferà quindi i messaggi a Bob con la sua chiave pubblica. La prima comunicazione tra il server e Alice sarà il server che chiede ad Alice la sua chiave pubblica in modo che possa essere utilizzata per comunicazioni future. Il server può quindi passare una chiave simmetrica crittografata con le proprie chiavi pubbliche a ciascuno di Bob e Alice da utilizzare per future comunicazioni.
  2. Fornisci al server una coppia di chiavi. Quando Bob si collega per la prima volta al server, Bob crea una chiave simmetrica che crittografa con la chiave pubblica del server. Il server e Bob lo usano per crittografare ulteriori comunicazioni. Quando il server contatta prima Alice, le passa la sua chiave pubblica. Alice risponde creando una chiave simmetrica e inviandola al server, crittografata con la chiave pubblica del server. Il server può quindi comunicare con Alice utilizzando questa chiave.

L'opzione 1 sopra utilizza ciò che chiamerò il modello SSH in cui i client generano coppie di chiavi uniche per ogni server. L'opzione 2 utilizza ciò che chiamerò il modello SSL in cui i server hanno la coppia di chiavi (sebbene SSL comunichi la chiave pubblica in un certificato firmato).

Se fai quanto sopra avrai un'ottima sicurezza. Detto questo, non sarà perfetto. Il problema è che sarai comunque vulnerabile agli attacchi MiTM .

Per funzionare in sicurezza, SSH richiede di convalidare l'impronta digitale della chiave pubblica del server la prima volta che ci si connette. Il protocollo non spiega come si convalida questo. La maggior parte degli utenti dice solo OK, senza convalidare, ma c'è una possibilità per un MITM lì.

SSL convalida automaticamente la chiave pubblica dal server convalidando la catena di certificati. Funziona solo perché c'è un keystore con certificati di root attendibili preinstallati con il tuo sistema operativo, browser o altro client. Senza questa convalida, la chiave pubblica nel certificato del server può essere falsificata senza rilevamento.

Non penso che riuscirai a fare molto meglio a meno che non usi un'infrastruttura di sicurezza esistente. Ad esempio, è possibile che il server esegua SSL e che il client convalidi il certificato passato nell'handshake SSL.

Non vedo questo come un problema in quanto sarai sicuro quanto SSH quando il client non convalida correttamente la chiave pubblica del server. IMO, è abbastanza buono.

Questo è un problema molto interessante. Buon divertimento!

PS: non c'è bisogno di scusarsi per il tuo inglese. È buono come quello di un madrelingua.

    
risposta data 19.04.2015 - 00:13
fonte
0

A seconda di dove ti trovi, direi che questo è un grande progetto di scuola superiore. La rotta ipsec + dnssec + pki + tls / ssl è una faccetta basata su protocollo di questo esercizio. Forse ti piacerebbe far apparire anche l'aspetto della sicurezza fisica delle cose. Ad esempio si richiama la posizione degli endpoint come fattore attenuante. Dopotutto, i fips level skiff per le attrezzature non sono lì per niente.

    
risposta data 19.12.2014 - 10:39
fonte
0

Fondamentale per la domanda, è se l'endpoint non è protetto, le chiavi, qualunque esse siano, possono essere ottenute, ed è per questo che per le transazioni sicure dell'endpoint, il terminale stesso è sotto l'egida del titolare - es. ATM, bancomat, ecc.

    
risposta data 19.04.2015 - 01:39
fonte
0

Bel progetto ma come al solito non si dovrebbe reinventare la ruota. Scrivere tali protocolli per l'uso della produzione è una cattiva idea in quasi tutti i casi. Raccomando di leggere il libro di Cryptography Engineering di Bruce Schneier. Non è una lettura leggera, ma eliminerebbe definitivamente tutte le tue domande. Prima di tutto penso che masterizzare le chiavi in eseguibili sia una pessima idea. Dovrebbe essere una chiave che protegge i tuoi dati sensibili non il metodo (vedi il principio di Kerckhoff). Rende anche la gestione delle chiavi un PITA. Perché coinvolgi il server nella negoziazione delle chiavi, è un requisito? Se non sbaglio, si utilizza la chiave "1234" per l'autenticazione peer. Potresti semplicemente averlo firmato dai client e verificato sul lato server usando le chiavi del client. Hai scritto "Una volta decisa una chiave comune, usa questa chiave o un hash di questa chiave". Ancora una volta, la forza chiave dovrebbe fornire sicurezza, non il metodo. I metodi possono essere riprodotti, i tasti non possono.

Tutto sommato, penso che dovresti usare un protocollo ben noto piuttosto che inventare il tuo. Se è solo un progetto che impara i protocolli di crittografia, in primo luogo ti consiglio di esaminare altri tipi di lavoro.

    
risposta data 19.04.2015 - 12:29
fonte
-1

La risposta (almeno per il mio lavoro) è l'host IPsec per il sito o l'host da ospitare con l'autenticazione PKI e la protezione delle chiavi private nell'hardware.

    
risposta data 19.12.2014 - 10:18
fonte

Leggi altre domande sui tag