Dovrei crittografare i dati sensibili dei moduli con JavaScript sul client?

3

Questo non è in alcun modo un sostituto per HTTPS, quindi per favore non presumere che sia per questo che sto facendo questa domanda. Sto esplorando e sono curioso. Sto cercando un input esperto su questo, e non sono del tutto sicuro di dove dovrei chiedere questo.

Ok, quindi dico che sto inviando informazioni davvero sensibili (informazioni bancarie per esempio). E voglio fare un ulteriore passo avanti per proteggerlo.

Con JavaScript, crittograferei i dati del modulo quando è stato inviato. Quindi lo decritterei sul server (back-end).

  • La prima opzione sarebbe quella di utilizzare la crittografia asimmetrica da sola. Criptare i dati del modulo al momento dell'invio, con la chiave pubblica. E dal momento che è pubblico, non può ferire il fatto che il cliente lo sappia. Quindi sul server, decrittografare i dati con la chiave privata. Ovviamente è privato e solo il server lo sa.

  • Molti algoritmi asimmetrici sono molto lenti da ciò che ho sentito e possono essere abbastanza limitati in termini di quanto è possibile crittografare (ad esempio RSA). Quindi per quanto riguarda la crittografia ibrida? Criptare i dati del modulo con la crittografia simmetrica (ogni volta viene generata una chiave casuale), quindi crittografare la chiave simmetrica con la chiave pubblica asimmetrica. Invia la chiave simmetrica insieme ai dati. Decifrare la chiave con la chiave privata, utilizzare la chiave per decrittografare i dati.

Che ne pensi? Sono un po 'perso per quale sarebbe meglio. E come andare su questo.

    
posta user10103279 20.09.2018 - 01:03
fonte

3 risposte

8

Il miglior caso qui è che stai perdendo tempo. In genere, la crittografia lato client su HTTPS in un'applicazione Web richiede molto lavoro, ma non offre ulteriore protezione.

Lo scopo di un ulteriore strato crittografico sarebbe quello di proteggersi da un MITM che in qualche modo è riuscito a violare la crittografia TLS. Ma un attaccante che ha fatto ciò potrebbe facilmente modificare semplicemente la sorgente JS della tua cripta extra, semplicemente spegnendola. Quindi questo sarebbe utile solo contro un MITM passivo che ha incrinato TLS, e che in realtà non è un modello di minaccia per cui vale la pena investire molta energia per proteggersi.

Si noti inoltre che le limitazioni della capacità di molti browser (Opera Mini, IE9) di generare numeri casuali sicuri rendono complicata la crittografia lato client. Non dovresti mai fare affidamento su Math.random per qualcosa di criptato relativo.

Dovresti concentrare la tua energia dove ha il massimo impatto. Invece di implementare la tua crittografia personale, assicurati di utilizzare la buona crittografia ottenuta gratuitamente con HTTPS. Se sei preoccupato per gli attacchi MITM, l'analisi dell'HSTS e del precaricamento potrebbe essere il tempo trascorso molto meglio.

    
risposta data 20.09.2018 - 15:50
fonte
0

Probabilmente no, ma ...

La maggior parte delle informazioni descritte nella risposta @Anders era corretta e dovrebbe essere riconosciuta come la risposta corretta.

Se supponiamo che stai eseguendo la crittografia specificatamente per la sessione client-server in corso, non ci saranno ulteriori vantaggi rispetto all'utilizzo di HTTPS.

Tuttavia, poiché hai spiegato che non stai cercando un'alternativa a HTTPS, presumo che tu stia esplorando uno dei seguenti scenari:

  1. Stai creando un'architettura server multilivello, in cui desideri solo server con autorizzazioni elevate per poter leggere i dati sensibili.

  2. Vuoi poter archiviare i dati a riposo in qualche database, ma vuoi solo alcuni dei tuoi server per poterli leggere.

  3. In realtà desideri solo la crittografia sul lato client, in cui il server non può leggerlo, ma può memorizzarlo.

Caveat Emptor

Tutti e tre questi scenari si basano sul presupposto che ci si può fidare del codice server in una certa misura. (Questo potrebbe funzionare in organizzazioni strutturate che hanno una pesante revisione del codice).

Metodi tradizionali

L'opzione 1 potrebbe essere implementata tradizionalmente abilitando CORS e consentendo al client di comunicare con il server "sopraelevato". Tuttavia, questo richiede l'apertura del server "sopraelevato" su Internet.

Questo in genere implica la tokenizzazione ed è un approccio utilizzato da molti processori di pagamento.

L'opzione 2 potrebbe essere implementata lato server, crittografando simmetricamente prima di inserire i dati nel database.

Metodi non tradizionali (per motivi di educazione)

Supponiamo tu abbia un mix unico di opzioni 1 & 2 oppure si desidera esplorare l'opzione 1 senza aprire il server al Web aperto.

Sì, è possibile utilizzare un cripto-sistema ibrido (asimmetrico + simmetrico) per crittografare efficacemente i dati che solo determinati server potrebbero decrittografare. L'implementazione di un tale crittosistema è una sfida e richiede una conoscenza crittografica espansiva che funzioni correttamente.

Per l'opzione 3, è possibile crittografare / decifrare simmetricamente lato client per proteggere i dati dell'utente. Ciò richiederebbe probabilmente la memorizzazione di una variabile in localStorage (per comodità), che comporta dei rischi (è più facile nascondere il codice che lo scansiona).

Questi approcci potrebbero contribuire a rendere più difficile per i dipendenti di un'organizzazione strutturata rubare i dati degli utenti. Funziona solo se il meccanismo di crittografia dei dati non può essere manomesso o se le credenziali non possono essere rubate.

La crittografia non sarà una pallottola d'argento in nessuno scenario che possa immaginare. Può mitigare parecchi vettori di attacco, ma non li risolverà tutti. Avresti bisogno di un'intensa revisione del codice.

    
risposta data 20.09.2018 - 20:57
fonte
-4

Il sistema che descrivi è la crittografia end-to-end (E2EE), che se implementata correttamente può garantire che nemmeno il server possa accedere ai contenuti. Tuttavia, per il tuo utilizzo, gli unici sistemi in grado di decodificare le "informazioni sensibili (SI) " saranno il client e il server.

Dopo aver inviato SI , scaricherai la chiave pubblica RSA del server, probabilmente RSA-2048 sarà sufficiente qui, poiché puoi generare nuove coppie di chiavi manualmente su base frequente. RSA con JavaScript potrebbe essere un buon punto di partenza, in quanto mostra come è possibile crittografare una stringa con la chiave pubblica e offrire opzioni di decrittografia come bene all'interno del codice sorgente. La memorizzazione della chiave privata RSA protetta potrebbe rivelarsi difficile. Puoi gestirlo usando PHP o Python (tramite un gateway CGI). Quindi assicurati che solo il compilatore abbia le autorizzazioni per accedere alla chiave privata, questo ridurrà i rischi. Come se il server web avesse permessi di accesso e fosse mai stato compromesso, avrebbe potuto accedere alla chiave privata.

Successivamente, è richiesta una chiave di crittografia simmetrica (SEK) . Stavo guardando Genera string / caratteri casuali in JavaScript , che sebbene non sia perfetto per questo scenario, dovrebbe dare una buona base per ciò che è richiesto.

Non avendo utilizzato un'implementazione JavaScript AES prima fornirò crittografia AES Javascript . Ho sentito che "JSAES è una potente implementazione di AES in JavaScript" sembrava una semplice opzione. Tuttavia, questa sarà la tua decisione.

Ora quando invii il testo cifrato (AES crittografato in chiaro) al server, devi assicurarti che il client sappia che la decrittografia era possibile e consentire la convalida. AES_Encrypt(plaintext, key) so AES_Encrypt("Validated", "$key") . Ciò garantisce che il server sia in grado di crittografare un messaggio con (chiave simmetrica crittografata) e il client sia stato in grado di decrittografare il messaggio previsto . Dovrei menzionare AES 128-bit o 256-bit sarà sufficiente allo stesso modo. Ovviamente, AES 256-bit è migliore, ma dato che l'RSA-2048 è il punto debole della catena, AES 128-bit con RSA-2048 potrebbe essere più ideale, poiché l'overhead sarà ridotto.

Ora sei convalidato. Assicurati che la chiave di crittografia simmetrica sia valida solo per X minuti, ad esempio 60 minuti. Prima che sia richiesta una nuova chiave di sessione. Ciò impedirà l'abuso del riutilizzo delle chiavi.

Per riassumere:

  • Recupera chiave pubblica RSA
  • Genera una stringa casuale di 32 caratteri (chiave simmetrica)
  • Encrypt (chiave simmetrica) con la chiave pubblica RSA
    • Produzione di testo cifrato
  • Invia il testo cifrato al server per la decodifica e la convalida
  • Decifra il testo cifrato con la chiave privata
  • Cifra il messaggio previsto (noto) utilizzando AES e la chiave simmetrica
    • AES_Encrypt("Validated", "$key")
  • Il client decrittografa e convalida che l'autenticazione sicura è completa.
risposta data 20.09.2018 - 03:11
fonte

Leggi altre domande sui tag