Archiviazione sicura delle credenziali di autenticazione di base nel database

2

Devo essere in grado di comunicare con un servizio API REST e memorizzare la coppia nome utente / password in un database.

Il client parla con l'API da un server all'interno della nostra DMZ, ma ottiene le credenziali da un database esterno alla DMZ all'interno della rete. Mi piacerebbe essere in grado di renderlo più sicuro in modo che se il server fosse compromesso sarebbe difficile accedere alle credenziali.

Qual è l'approccio migliore per archiviare le credenziali in modo sicuro? Non posso usare un sale & meccanismo di hashing perché l'API richiede la coppia nome utente / password come testo semplice e controllano il processo di autenticazione.

Piattaforma e lingue in uso: di Windows / .NET / C #

    
posta user183872 06.09.2016 - 16:05
fonte

3 risposte

1

Una soluzione

Affrontare solo il problema relativo alla memorizzazione sicura delle credenziali. Esiste sempre un rischio poiché la chiave di decodifica deve ancora essere memorizzata da qualche parte.

Ad esempio, è possibile utilizzare OpenSSL per crittografare una stringa di testo e quindi memorizzarla nel database sul server "non sicuro". Dovresti utilizzare anche un metodo di crittografia reversibile per questo.

Tale compito potrebbe essere realizzato con un semplice script PHP:

openssl_encrypt(PLAINTEXT, ENCRYPTION_METHOD, KEY, OPENSSL_OPTIONS, INITIALIZATION_VECTOR)

Quindi nel contesto, per esempio. (Assicurati di aggiungere 16 byte di padding prima della crittografia e rimuovi 16 byte di padding sulla decrittografia, questo può essere rimosso specificando specifiche opzioni OpenSSL, tuttavia per facilità puoi semplicemente aggiungere e rimuovere il padding. come un grado di offuscamento, in una certa misura, in questo esempio, sono stati usati i caratteri 16 '=', ma può anche dipendere enormemente da come viene configurata l'installazione di OpenSSL, tuttavia, per esperienza personale, faccio sempre solo attenzione Chiamalo un po 'di "sale" se vuoi ..)

openssl_encrypt("================username:password", "aes-128-cbc", "StRoNGeNcrYptIOnKey", 0, "16ByteIV--Random")

L'esecuzione di quanto sopra avrebbe prodotto qualcosa di simile a:

+VUYZEh3FII7HRvJ8Qm8glERsgfsSKG9tE8Zyr2EJLL+9VaF7+41q/MeL8R1++L1

Puoi quindi eseguire la decrittazione successiva:

openssl_decrypt("+VUYZEh3FII7HRvJ8Qm8glERsgfsSKG9tE8Zyr2EJLL+9VaF7+41q/MeL8R1++L1", "aes-128-cbc", "StRoNGeNcrYptIOnKey", 0, "16ByteIV--Random");

In produzione:

================username:password

Ci sono una vasta gamma di algoritmi di crittografia che possono essere utilizzati. C'è anche un articolo su PHP.net che mostra come questo può essere raggiunto, e include anche Linux Esempi di CLI, se desideri farlo anche tramite gli script di bash.

BEAR IN MIND

Dovrai comunque conservare una copia in chiaro della chiave di crittografia sul tuo dispositivo se questo è un processo automatico, che potrebbe non essere l'ideale, né sarebbe raccomandato. Non c'è niente che ti impedisca di utilizzare questo approccio e di archiviare i dati crittografati sul tuo server esterno, ma prenditi solo un momento per valutare le implicazioni sulla sicurezza di memorizzare una password in chiaro su un server.

Se ti senti nevrotico

Potresti anche cifrare le credenziali una volta con un algoritmo e quindi ricrittare il testo cifrato con un altro algoritmo completamente diverso.

Fino a te dipende da quanto sono sicuri i dati e quanto tempo / giustificazione / etc della CPU vuoi dedicare a questo.

Breve storia

Hai bisogno di una soluzione di crittografia reversibile se vuoi essere in grado di recuperare testo in chiaro dal testo cifrato e viceversa.

    
risposta data 06.09.2016 - 16:55
fonte
1

Penso che il compito sia molto difficile. Il tuo server ha accesso alle credenziali. Ciò significa che il processo in esecuzione ha tutti i privilegi di cui ha bisogno per

  1. recupera i dati rilevanti da un DB (crittografato o meno)
  2. accedere agli elementi pertinenti da decodificare (ad esempio, una chiave nel file system utilizzata per la crittografia / decrittografia)

Se il tuo server è compromesso, questo significa per me che qualcuno inietta il codice nel server e ottiene una shell almeno come utente che esegue il processo (come www-data per apache). (Se è peggio di così, allora è game over.)

Ciò significa che l'attaccante ha la possibilità di accedere al DB e molto probabilmente di accedere anche alla chiave di crittografia.

Detto questo, posso immaginare 2 modi per rafforzare il sistema.

Chiave di crittografia posseduta da root. Potresti scrivere un server avviato come root, quindi rilasciare i processi figlio di lavoro che effettivamente eseguono il lavoro. La prima cosa che fa ogni bambino è passare a www-data. Apache funziona in questo modo. La chiave di crittografia si trova nel file system in un file con le autorizzazioni 0400 (accesso in lettura solo per root). Il dispatcher legge la chiave subito dopo l'avvio. Dopo che i bambini sono biforcati, consegna la chiave di crittografia ai bambini tramite un metodo di comunicazione interprocesso. Se uno dei processi figli è compromesso, il processo in esecuzione come www-data non può accedere alla chiave nel file system (solo root può). L'utente malintenzionato dovrebbe trovare un modo per ispezionare la memoria del processo per trovare la chiave. Non impossibile ma sicuramente niente per i principianti.

Archiviazione e crittografia separate. Supponiamo che i tuoi clienti debbano autenticarsi sul server (dovrebbe essere comunque così). Quindi è possibile separare le attività di archiviazione e crittografia. Un servizio legge la password crittografata e la invia al client. Un secondo servizio, che può essere eseguito sulla stessa casella ma come utente diverso esegue la decrittografia. Quindi il cliente deve eseguire 2 chiamate. Cosa succede se uno dei servizi è compromesso? Quindi è possibile decodificare una password crittografata xor accedere ai record crittografati nel DB. Il punto cruciale qui è che devi assicurarti che diciamo che il primo servizio compromesso non può inviare la password crittografata al secondo servizio. Ma ciò non dovrebbe essere possibile se il client si autentica (e nessuno di questi 2 server dovrebbe conoscere le credenziali di cleartext).

In attesa di commenti della comunità.

    
risposta data 06.10.2016 - 18:09
fonte
1

L'opzione migliore è quella di proteggere il servizio REST con un certificato client (invece delle credenziali di autenticazione di base), se questa è un'opzione. Ciò è solitamente ottenibile senza modificare il codice del servizio, in genere può essere fatto tramite la configurazione della piattaforma del server Web.

Se ciò non è possibile, puoi comunque proteggere le credenziali di autenticazione di base con la stessa sicurezza che protegge l'archivio certificati, come in questo:

  1. Genera un certificato per te stesso e importalo (inclusa la chiave privata) in un archivio certificati appropriato sul server, probabilmente un archivio certificato privato per il processo del server web. Non hai menzionato su quale piattaforma sei. Se sei su Windows, puoi inserire il certificato nell'archivio utente per l'account del servizio del dominio dell'app.

  2. Codifica le credenziali di autenticazione di base utilizzando la chiave pubblica del certificato. Memorizza le credenziali crittografate nel tuo database, nel file di configurazione o in qualsiasi altra cosa usi il tuo client REST.

  3. Quando è necessario chiamare il servizio REST, recuperare la chiave privata del certificato dall'archivio certificati e utilizzare la chiave privata per decrittografare le credenziali.

In teoria si tratta di una sorta di sicurezza per oscurità, ma ha il vantaggio di sfruttare tutto il rafforzamento del sistema che viene fatto nei negozi di cert, che sono ovviamente molto sensibili. Ora, forse un hacker sarà in grado di entrare in quel negozio di certificati, ma se ci riuscirà allora probabilmente avrai problemi molto più grandi.

Questo articolo qui sembra contenere tutti i dettagli che tu d bisogno.

    
risposta data 06.12.2016 - 02:45
fonte

Leggi altre domande sui tag