Le altre risposte già dicono No, "roll your own" is rarely a good password storage scheme and yours is no exception.
Vorrei aggiungere: non è un buon schema per archiviare / comunicare il nome utente.
Stai praticamente facendo l'hashing. Niente di male in questo, tranne:
- Stai utilizzando una funzione non progettata come funzione di hash sicura. Essendo un cifrario è sicuramente sulla "scala sicura" della scala, ma l'hashing implica anche evitare le collisioni di hash. Una cifra non è in genere ottimizzata per non avere collisioni. È noto che gli One-Time Pad sono indistruttibili, poiché hanno il numero massimo di collisioni. Quindi un codice strong fa un hash povero in termini di collisioni.
- Se memorizzi nome utente e nome utente -codificato-con-password ci sono più vulnerabilità:
- In questo caso, se il tuo database viene violato l'autore dell'attacco non solo ottiene
the username encrypted with an unknown password
. Ottiene anche il testo chiaro aka. nome utente. Quindi è una chiara analisi del testo, che per alcuni algoritmi è molto più semplice della forza bruta.
- Collisioni hash: l'autore dell'attacco non ha bisogno di sapere la password ma qualsiasi che produce la stessa crittografia per un testo chiaro breve e specificato. Questo potrebbe essere ancora più semplice dell'analisi del testo in chiaro.
- Se non memorizzi il nome utente ma fai affidamento su un singolo valore trasmesso combinato, ci sono ancora degli svantaggi:
- In questo caso, probabilmente non hai considerato le collisioni di hash. Che dire di due utenti, che hanno lo stesso nome utente? Che ne dici di due idioti, che hanno lo stesso nome utente e la stessa password? Che dire delle collisioni di hash di diversi nomi utente e password per puro caso (ricordate: le cifre non sono ottimizzate per evitare collisioni!)?
- In ogni caso c'è l'attacco "Passa l'hash": un utente malintenzionato che annusa le comunicazioni di rete può semplicemente emulare l'applicazione per trasmettere gli stessi dati dell'utente. Hai fatto qualcosa a riguardo? In caso contrario, è per questo che non dovresti "eseguire il rollover".
Spesso il protocollo di trasmissione è tanto importante quanto la sicurezza quanto una strong funzione crittografica, indipendente dall'hashing e dalla crittografia. Un cattivo protocollo può esporre la tua funzione ad attacchi non adatti, in particolare "attacchi di canali laterali" come "passare l'hash" o "uomo nel mezzo" che aggirano l'effettiva criptoanalisi sul lato dell'attaccante.
Lo schema di archiviazione della password potrebbe essere soggetto a tali attacchi, perché non è stato specificato, se il nome utente è anche memorizzato in testo non crittografato. Così facendo esponi il tuo schema agli attacchi descritti sopra. Non memorizzarlo in testo chiaro potrebbe richiedere un protocollo di trasmissione soggetto ad attacchi come descritto sopra.
Ecco alcune considerazioni aggiuntive sui protocolli di trasmissione nel tuo caso, leggermente generalizzate:
Se non hai fatto nulla per l'attacco "passa l'hash", allora il tuo schema è peggiore di un sacco di altri. Un utente malintenzionato non ha bisogno di hackerare la tua base di dati né crackare il tuo codice. Ottiene ciò di cui ha bisogno gratuitamente sniffando il traffico di rete.
L'HTTPS può essere sufficiente, sebbene possa essere aggirato da "man in the middle": gli utenti non controllano i certificati di autenticazione, vero? Un utente malintenzionato apre semplicemente una connessione non autenticata ma crittografata al tuo utente e qualsiasi altra connessione sia prevista per te.
Un ulteriore schema Challenge-Response può aggiungere sicurezza. Prima di accedere, il client riceve una stringa casuale (una sfida) una tantum che deve compilare nell'hash (risposta). Un utente malintenzionato non può riutilizzare un hash annusato, perché la richiesta non viene riutilizzata.
Ma ancora una volta, non è necessario "eseguire il rollover".