Domanda

Sto creando un sito web PHP che coinvolge gli utenti la firma, e mi chiedo circa le migliori pratiche per i codici "conferma e-mail".

I nuovi utenti devono confermare i loro indirizzi e-mail - faccio questo generando un codice e inviarlo all'utente in una e-mail, che può quindi utilizzare per attivare il suo account. Piuttosto che immagazzinare questa chiave in un database, sto usando un po 'di soluzione a portata di mano: il codice è il risultato di:

md5("xxxxxxxxx".$username."xxxxxxxxxxx".$timestamp."xxxxxxxxx");

Dove $ timestamp si riferisce al tempo user-creazione. Nel complesso sono rimasto abbastanza soddisfatto di questo, ma poi ho avuto modo di pensare, è questo abbastanza sicuro? E per quanto riguarda la possibilità di collisioni? E ho anche bisogno di generare codici per la reimpostazione della password, ecc Se ho usato una metodologia simile, una collisione potrebbe tradursi in un utente inavvertitamente reimpostare la password di un altro utente. E questo non va bene.

Quindi, come si fa a fare queste cose? Il mio pensiero era un tavolo con il seguente formato:

codePK (int, a-I), userID (int), type (int), code (varchar 32), date (timestamp)

Dove 'tipo' sarebbe 1, 2 o 3 significato di "attivazione", "cambiamento e-mail" o "reimpostazione della password". È questo un buon modo per farlo? Avete un modo migliore?

Con un metodo simile al precedente, potrei eliminare automaticamente qualcosa di più di due giorni senza usare cron-job? Il mio ospite (nearlyfreespeech.net) non li supporta. Se possibile vorrei evitare di avere un cron-job su un host esterno che wget uno script che cancella le cose, in quanto questo è solo disordinato = P.

Grazie!
Mala

Aggiornamento:
Per chiarire: ho capito l'unico modo per sicuro e sicuro andare su questo compito è quello di utilizzare un database, che è ciò che la funzione originale stava cercando di evitare. La mia domanda è su come dovrebbe essere strutturata la tabella (o tabelle?). Qualcuno mi ha suggerito di farla finita con codePK e solo rendere il codice di PK. Così, in breve, la mia domanda è:? È questo ciò che si fa

È stato utile?

Soluzione

Quando ho bisogno di questi tipi di trucchi che di norma è di uno dei due motivi, entrambi menzionati da voi:

  1. Come chiave utilizzata per le email di verifica inviata all'utente
  2. Come una chiave usata per reimpostazione della password collegamenti

Naturalmente ci sarebbero numerose altre occasioni in cui si desidera considerare l'utilizzo di una tale costruzione.

Prima di tutto, si dovrebbe sempre utilizzare un qualche tipo di sale che è nascosto e che solo tu conosci. Si noti che questo sale deve essere diverso per ogni utente. Il sale potrebbe ad esempio essere calcolato come sha256(something random). Questo sale deve quindi essere memorizzato nel database con il nome utente e la password (hash con il sale).

Cosa farei quando si invia il link di reimpostazione password è quello di creare un altro sale (non dare all'utente l'accesso a qualsiasi cosa hash con il sale. Lui conosce la sua password, in modo da utilizzare bruteforce che potesse potenzialmente capire il sale). L'altro sale, che è essenzialmente solo un hash di una stringa casuale (si potrebbe desiderare di andare per md5 qui, come lei ha ricordato che la lunghezza è un problema), si dovrebbe quindi salvare nel database.

Spesso si può solo ottenere via con l'aggiunta di una colonna aggiuntiva alla vostra tabella utenti. Questo, tuttavia, ha anche alcuni problemi, soprattutto che una volta che la password è stata reimpostata o l'utente è stato attivato, si togliere la chiave dal database, che si traduce nella maggior parte dei file con valori nulli, che a sua volta porta alcuni altri problemi .

Che cosa questo si riduce essenzialmente a:

    password
  • Hash tuoi degli utenti che utilizzano un sale unico-per-il-utente ( e , forse un sale globale, segreto).
  • Genera una chiave per hashing un certo numero di fonti casuali o pseudocasuali come timestamp, mt_rand() o anche random.org se si vuole veramente roba casuale.
  • Non utilizzare mai il sale globale o il sale che è unico per l'utente per l'hashing tutto ciò che l'utente ottiene l'accesso a, incluse le chiavi di reimpostazione della password, chiavi di attivazione, ecc.

Si prega di non che io sono affatto un esperto di sicurezza, e probabilmente ho dimenticato un certo numero di cose, e forse ho detto alcune cose di pratica molto male. Solo i miei 5 centesimi; -)

Altri suggerimenti

Perché utilizzare uno dei dati dell'utente come base per la chiave di autorizzazione?

Presumo che stai memorizzazione dei dati de-attivato in un database e allora perché non basta aggiungere una registrazione aggiuntiva che è semplicemente una chiave casuale (forse un md5'ed uniqid con qualche manipolazione addizionale) e quindi controllare che contro?

E 'stato abbastanza sicuro fino a quando il punto in cui hai pubblicato il tuo metodo su Internet! Questo perché si fa affidamento sul sicurezza tramite segretezza, che non è una buona idea.

Si dovrebbe utilizzare una sorta di funzione di hash con chiave o MAC idealmente, che incorpora una chiave segreta nota solo a voi.

Perché non rendere campo codice indice univoco? Quindi non ci sarà mai collsisions?

Inoltre, se non c'è bisogno di creare hash da input dell'utente e corrispondere al hash database (-mail di conferma, reimpostazione della password ecc) - è possibile aggiungere stringa casuale al corpo hash, come md5('xxx'.$username.'xxx'.time().'xxx'.rand())

Perché non chiedere all'utente di inserire il proprio nome utente e il loro codice, eliminando così qualsiasi problema con la collisione? Non si perde nulla della sicurezza-saggio come si sta ancora chiedendo la chiave che otterrebbero dal email, ma che ci si smette di loro di essere in grado di reimpostare le password di altri utenti.

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