Domanda

Di recente abbiamo avuto un audit di sicurezza che ha messo in luce diversi punti deboli nei sistemi esistenti. Una delle attività che ne sono derivate è che dobbiamo aggiornare il nostro sistema di credenziali dei partner per renderlo più sicuro.

Il "vecchio" il modo di fare le cose era generare una (cattiva) password, darla al partner con un ID e quindi avrebbero inviato quell'ID e una copia codificata Base 64 di quella password con tutte le loro richieste XML su https. Li decodifichiamo e li convalidiamo.

Queste password non cambieranno (perché quindi i nostri partner dovrebbero apportare modifiche alla codifica / configurazione per cambiarle e coordinare le scadenze delle password con centinaia di partner per più ambienti sarebbe un incubo) e non devono essere inseriti da un essere umano o leggibile dall'uomo. Sono aperto a cambiare questa situazione se esiste un'implementazione migliore ma ancora relativamente semplice per i nostri partner.

Fondamentalmente si riduce a due cose: ho bisogno di un sistema di generazione di password Java più sicuro e per assicurarmi che vengano trasmessi in modo sicuro.

Ho trovato alcuni generatori di password a rotazione manuale, ma niente che si sia distinto come un modo standard per farlo (forse per una buona ragione). Potrebbe esserci anche un modo più sicuro per trasmetterli rispetto alla semplice codifica Base 64 su https.

Cosa faresti per il generatore di password e pensi che il metodo di trasmissione in atto sia abbastanza sicuro per questo?

Modifica: l'XML viene visualizzato in un messaggio SOAP e le credenziali si trovano nell'intestazione e non nell'XML stesso. Inoltre, poiché le password sono un'operazione una tantum per ogni partner quando le impostiamo, non siamo troppo preoccupati per l'efficienza del generatore.

È stato utile?

Soluzione

Generazione password

Per quanto riguarda la codifica di una password per la trasmissione, l'unica codifica che aggiungerà veramente sicurezza è la crittografia. L'uso di Base-64 o esadecimale non è per sicurezza, ma solo per poterlo includere in un formato di testo come XML.

L'entropia viene utilizzata per misurare la qualità della password. Quindi, scegliendo ogni bit con una "gettoniera" casuale ti darà la migliore password di qualità. Vorresti che le password fossero forti come le altre chiavi crittografiche, quindi raccomanderei un minimo di 128 bit di entropia.

Esistono due metodi semplici, a seconda di come si desidera codificare la password come testo (che non ha importanza dal punto di vista della sicurezza).

Per Base-64 , usa qualcosa del genere:

  SecureRandom rnd = new SecureRandom();
  /* Byte array length is multiple of LCM(log2(64), 8) / 8 = 3. */
  byte[] password = new byte[18];
  rnd.nextBytes(password);
  String encoded = Base64.encode(password);

Quanto segue non richiede di creare un codificatore Base-64. La codifica risultante non è così compatta (26 caratteri anziché 24) e la password non ha tanta entropia. (Ma 130 bit sono già molti, paragonabili a una password di almeno 30 caratteri scelti da un essere umano.)

SecureRandom rnd = new SecureRandom();
/* Bit length is multiple of log2(32) = 5. */
String encoded = new BigInteger(130, rnd).toString(32); 

La creazione di nuovi oggetti SecureRandom è costosa dal punto di vista computazionale, quindi se hai intenzione di generare password frequentemente, potresti voler creare un'istanza e tenerla in giro.

Un approccio migliore

Incorporare la password nell'XML stesso sembra un errore.

Prima di tutto, sembra che tu voglia autenticare un mittente prima di elaborare tutti i documenti che ti inviano. Supponiamo che io odio le tue viscere e che inizi a inviarti file XML giganti per eseguire un attacco denial of service. Vuoi analizzare l'XML solo per scoprire che non sono un partner legittimo? Non sarebbe meglio se il servlet respingesse in anticipo le richieste di utenti non autenticati?

In secondo luogo, le password dei tuoi legittimi partner sono state protette durante la trasmissione da HTTPS, ma ora sono probabilmente memorizzate "in chiaro" sul tuo sistema da qualche parte. Questa è una cattiva sicurezza.

Un approccio migliore sarebbe quello di autenticare i partner quando ti inviano un documento con credenziali nelle intestazioni della richiesta HTTP. Se consenti solo HTTPS, puoi estrarre completamente la password dal documento e inserirla in un HTTP " base " autenticazione invece. È protetto da SSL durante la trasmissione e non è archiviato sul tuo sistema in chiaro (memorizzi un hash unidirezionale a fini di autenticazione).

L'autenticazione HTTP di base è semplice, ampiamente supportata e sarà molto più facile da implementare per te e i tuoi partner rispetto ai certificati client SSL.

Protezione del contenuto del documento

Se il contenuto dei documenti stessi è sensibile, dovrebbero essere crittografati dal mittente e archiviati da te nella loro forma crittografata. Il modo migliore per farlo è con la crittografia a chiave pubblica, ma sarebbe un argomento per un'altra domanda.

Altri suggerimenti

Non potresti utilizzare le chiavi SSL per l'autenticazione?

Non sono chiaro il motivo per cui la trasmissione delle password su SSL - tramite HTTPS - sia considerata "non sicura". dal team di audit. Quindi, quando chiedi due cose, sembra che la seconda - garantire che le password vengano trasmesse in modo sicuro - sia già gestita correttamente.

Per quanto riguarda il primo, dovremmo sapere cosa circa l'audit ha rivelato le tue password insicure ...

Abbandonerei l'intero approccio alla password e inizierei a utilizzare i certificati client che consentono una connessione SSL autenticata su 2 lati.

Devi generare e firmare singoli certificati per ciascun cliente. Nell'handshake SSL, si richiede il certificato del cliente e lo si verifica. Se fallisce, la connessione termina con un codice di stato 401.

I certificati possono essere revocati in qualsiasi momento dalla tua parte, consentendo di disconnettere facilmente gli ex clienti.

Poiché tutto ciò avviene nell'handshake prima della comunicazione, non è possibile inondare i dati del server.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top