PHP - Serve aiuto per crittografare / hash una password per una piccola applicazione

2

Ho creato un piccolo script per il lavoro. È uno script Web interno, ma deve essere ospitato nel nostro dominio pubblico, quindi ho creato un sistema di accesso basato su PHP molto piccolo utilizzando un modulo di accesso e un controllo di sessione. Invece di dover definire la password in formato testo, qualcuno può mostrarmi come aggiungere la password in un formato crittografato, senza l'uso di un database o di un file esterno?

Il mio codice di accesso è pubblicato nella parte inferiore - appena sopra è la linea che vorrei cambiare questa password con un qualche tipo di crittografia in modo che non possa essere letto in chiaro se qualcuno ha accesso ai file, o PHP si avvita e inizia a stampare in testo normale. Ho provato a cercare su google e cercando SE tutto è relativo a DB e file di configurazione esterni.

$ logins = array ('username' = > 'password123');

    <?php session_start();

if(isset($_POST['Submit'])){
$logins = array('username' => 'password123');


$Username = isset($_POST['Username']) ? $_POST['Username'] : '';
$Password = isset($_POST['Password']) ? $_POST['Password'] : '';


if (isset($logins[$Username]) && $logins[$Username] == $Password){


$_SESSION['UserData']['Username']=$logins[$Username];
  if (isset($_SESSION["login_redirect"])) {
        header("Location: " . $_SESSION["login_redirect"]);
        unset($_SESSION["login_redirect"]);
    } else {
        header("Location: index.php");
    }
exit;
} else {

/* Login failed display message */
$msg="<span style='color:red'>Invalid Login Details</span>";
}
}

Grazie per qualsiasi aiuto!

P.S. Lo script è ospitato / servito da HTTPS e HTTP2 su PHP 7x e apache in caso faccia qualche differenza.

Modifica:

Per cominciare c'è solo 1 utente e password. potrebbero esserci altri utenti in futuro. Ma così com'è ora ne basta uno per il personale. Al momento non è necessario registrare le azioni degli utenti ecc.

Lo script sarà su un sottodominio di un sito Web pubblico che ha il suo WAF che protegge anche la sub-dir, quindi verranno prese le cose come la forza bruta. Abbiamo anche Mod Security e CSF sul server che aiuteranno anche.

Lo script è ospitato sul lato pubblico in quanto la società non utilizza una intranet interna, un server VPN o LDAP / AD, ecc. Lo script deve essere accessibile anche fuori dall'ufficio, nel caso in cui il capo decida di lavorare da casa o Starbucks ...

Voglio solo proteggere la parte della password perché è archiviata in chiaro nel file login.php. Se qualcuno dovesse accedervi sul server o via FTP ecc, avrebbero un facile accesso alla password. E come accennato dovrebbe interruzione di PHP non voglio password visualizzata come testo in chiaro sullo schermo.

Quindi aggiorna la mia domanda un po '. Qualcuno può darmi dei puntatori iniziali per sostituire la password con un sistema di password con hash?

Ancora una volta capisco che un numero di persone qui suggerirà l'uso di intranet aziendali, VPN, piattaforme dedicate blah blah, per favore comprendi che questa è una piccola azienda e un progetto ancora più piccolo. Cose come la perdita di password da parte del personale sono meno preoccupanti. Sono più interessato a proteggere la password già esistente e a mantenere la sceneggiatura più piccola e leggera possibile.

    
posta Greg 07.09.2018 - 18:18
fonte

3 risposte

3

Alcuni punti:

  • Le password devono essere sottoposte a hash, non crittografate. La crittografia è reversibile; qualcuno che non dovrebbe avere accesso ma può vedere il codice sorgente dell'app può trovare la password crittografata e la sua chiave di crittografia, decrittografare la password e quindi ottenere l'accesso. Gli hash sono a senso unico; non è possibile convertire un hash digest nel testo che è stato sottoposto a hash.
    • Preferisci idealmente una lenta funzione hash (PBKDF2, bcrypt, scrypt o argon2, in ordine di sicurezza crescente) perché gli hash veloci possono essere forzati brutalmente con l'hardware moderno.
    • Sicuramente vuoi usare un hash salato (gli algoritmi di cui sopra si aspetteranno o genereranno automaticamente un salt), altrimenti l'attaccante può usare una tabella arcobaleno (o semplicemente Google il digest di hash) per trovare la password molto rapidamente .
  • Il sistema che descrivi è troppo fragile. Con ogni utente di questo sistema che condivide una password, sarà trapelato. Qualcuno lascerà l'azienda, o effettuerà l'accesso da un sistema compromesso, o lascerà il messaggio su una nota appiccicosa dove non dovrebbe, o lo invierà su un canale di comunicazione non sicuro, o qualcosa del genere. In altre parole, non esiste un modo molto sicuro per fare ciò che stai chiedendo. Dovresti davvero avere il controllo degli accessi per utente, e sì, probabilmente significa un database.
    • Inoltre, perdi capacità di registrazione significative quando non fai distinzioni tra gli utenti. Se qualcuno entra e abusa del sistema, non puoi sapere chi lo ha fatto perché tutti gli accessi sono uguali. Ovviamente, nel frammento di cui sopra, non hai alcuna registrazione in assoluto ...
  • Non menzioni alcun tipo di protezione brute-forcing della password, senza la quale un utente malintenzionato esterno può probabilmente violare la password, nel peggiore dei casi, qualche giorno di tentativi.

Esistono modi corretti per gestire lo scenario, ma funzionano tutti in modo diverso rispetto a quello che stai descrivendo.

  1. Limita il sito interno agli indirizzi IP intranet (rete aziendale) e richiede che utenti esterni si trovino su una VPN.
  2. Delega l'autenticazione all'autorità di accesso interna. Se si dispone di un server LDAP / Active Directory, è possibile passare la richiesta di autenticazione fino ad esso. Infatti, se usi Active Directory e IIS (probabilmente no, da PHP, ma ancora), è semplice come impostare l'app per richiedere "Autenticazione di Windows".
  3. Delega l'autenticazione a un fornitore esterno, se ne usi uno. Ad esempio, se la tua azienda utilizza Google Suite, puoi utilizzare Google SSO (Single Sign-On) e verificare che l'utente disponga di un indirizzo email aziendale. Puoi anche utilizzare un provider di autenticazione esterno, come Auth0.
  4. Garantisco che bisogno sia ospitato sul tuo dominio pubblico, anche se senza sapere perché pensi così non posso offrire approcci migliori. Tuttavia, questo scenario è esattamente ciò che i server Intranet esistono e possono comunicare con il server Web pubblico su canali back-end (o tramite CORS attraverso il client), se necessario.

Più in generale, il fatto che tu stia chiedendo questo indica che probabilmente non dovresti provare a lanciare il tuo sistema di autenticazione. Senza saperne di più sullo scenario, non posso dire esattamente quali sono i rischi, ma sarei molto sorpreso se riuscissi a renderli conto di tutti con un sistema come questo. La sicurezza è difficile; è un'idea molto migliore per andare con un sistema collaudato sviluppato da persone che sanno cosa stanno facendo.

    
risposta data 07.09.2018 - 23:19
fonte
1

cosa / come?

Utilizza password_hash . Copia il valore di stringa restituito e incollalo nell'origine. Utilizza password_verify per verificare se la password è corretta.

L'algoritmo di password_hash può essere PASSWORD_DEFAULT . Aumentare il parametro di costo di bcrypt è probabilmente una buona idea. Argon2 è migliore se i parametri di costo sono ottimizzati, ma non so se i valori di default siano buoni o meno.

password_verify prende la password fornita al modulo di login come primo argomento e una stringa restituita da password_hash per il suo secondo.

Perché?

Questo è chiamato hashing della password. (Non crittografia). Gli algoritmi di hash delle password sono una variazione delle funzioni hash crittografiche. Sono processi a senso unico. Non è possibile recuperare la password dell'utente senza prima averla indovinata correttamente. È ancora compito del creatore della password scegliere una password sicura.

Nel cracking delle password offline, il cracker può provare le password candidate una dopo l'altra, facendo un lavoro equivalente a quello che password_verify fa, finché non trovano una corrispondenza. (Il cracking offline è quando qualcuno ruba un hash della password e prova a verificarlo sul proprio computer, ignorando cose che il server potrebbe fare come limitando la velocità.)

Gli algoritmi di hash delle password cercano di contenere password meno potenti costringendo chiunque desideri testare una password per svolgere più lavoro per ipotesi, sia legittima che illegittima.

Cos'altro?

Dovresti comunque implementare limitando il tasso . Forse anche blocchi di account temporanei. Anche l'elenco di indirizzi IP in bianco sarebbe una buona idea, ma potrebbe causare problemi di usabilità in alcune situazioni. White-listing non è neanche difesa infallibile.

Per eseguire lockout e limitazione della velocità è necessario un tipo di archivio di lettura / scrittura. Le variabili di sessione non funzionerebbero perché un utente malintenzionato potrebbe semplicemente iniziare una nuova sessione. Forse riconsiderare le tue esigenze per questo motivo. Oppure trova un altro archivio come un file di lettura / scrittura al di fuori della radice del documento o dell'archivio dei valori-chiave.

Per nascondere gli hash delle password da qualcuno con accesso a sorgenti PHP, il metodo di sola lettura più semplice di cui ho sentito parlare è usare SetEnv o fastcgi_param ma che probabilmente conta come "file conf esterni".

Nascondere gli hash, se funzionasse, renderebbe più difficile sottrarre gli hash delle password. Se non riescono a ottenere gli hash, non possono usare il cracking offline. Comunque non penso che sarà di grande aiuto. Forse non sei ancora hackerato. Forse qualcuno ha hackerato il tuo server e ha molto più accesso che solo la possibilità di leggere il codice sorgente PHP. È possibile che qualcuno abbia solo accesso in lettura a sorgenti PHP, ma in realtà non dovrebbe essere probabile. Penso che il tuo sforzo sia meglio speso evitando bug o errate configurazioni per evitare che perdite di sorgenti PHP si verifichino in primo luogo.

    
risposta data 07.09.2018 - 23:30
fonte
1

Chiedi a un gruppo di addetti alla sicurezza di quanta sicurezza hai bisogno e ti diranno "un sacco".

Sì, mantenere la password in chiaro come si sta facendo è una cattiva idea. Mantenere la password codificata nel programma è una cattiva idea.

Come dice @FutureSecurity, PHP ha una funzione utile password_hash che astrae tutte le complessità di gestione delle password (non hai solo una password hash, che fai con sha1 () o md5 (), dovresti aggiungi un sale e altro anche le cose ).

Ma cosa vuoi qui? Se si impara a essere un programmatore migliore, allora vai a leggere su password_hash (), ma se vuoi semplicemente applicare un controllo di accesso sicuro, allora potresti usare meglio Meccanismi di autorizzazione di Apache .

    
risposta data 11.09.2018 - 18:58
fonte

Leggi altre domande sui tag