Quello che stai facendo qui è in effetti la definizione di una funzione di hash: data una funzione di crittografia Encrypt (K, M) dove K è la chiave e M è il testo in chiaro da cifrare, tu definisci Hash (P) = Encrypt (P, P). Quindi stai inventando una nuova funzione crittografica.
Innanzitutto, per l'hashing della password, non hai bisogno di alcuna vecchia funzione di hash, perché deve essere resistente al tentativo di forza bruta, dove l'utente malintenzionato indovina quale potrebbe essere la password, calcola Hash (indovina) e confronta il risultato con l'hash memorizzato. Qualunque algoritmo di hash tu faccia, devi rinforzarlo per includere il sale (in modo che gli hacker debbano crackare ciascun hash singolarmente anziché chiudere tutti gli account contemporaneamente e far cadere le password più deboli) e rendere la funzione hash lenta (perché fa male l'attaccante, che ha bisogno di fare molte supposizioni sbagliate, più del difensore, che per lo più verificherà i tentativi corretti). Vedi Come fare in modo sicuro le password di hash? per una spiegazione più dettagliata.
Puoi costruire una funzione hash lenta e salata da una normale funzione di hash, con una costruzione come SSH (P, S) = Hash (Hash (... Hash (P + S) ...)) (dove P + S è la concatenazione ). Questo non è necessariamente il modo migliore per farlo - ad esempio, una buona funzione di hashing della password per gli usi tipici dovrebbe richiedere molta memoria, perché i server hanno molta più memoria di hardware specializzato per cracking delle password. Ma è un buon inizio.
Il problema rimane se Hash (P) = Encrypt (P, P) è una buona funzione di hash. Questo non è automatico; fai attenzione che alcune analisi della sicurezza degli algoritmi crittografici si basano sulla chiave e il testo in chiaro è indipendente.
Una delle maggiori difficoltà è che le dimensioni della chiave nella maggior parte degli algoritmi di crittografia sono strongmente limitate, spesso costanti. Ad esempio, l'algoritmo di crittografia standard AES accetta solo tre dimensioni di chiave (8, 12 o 16 byte). Se la password (più sale) è troppo corta, puoi applicarla con un carattere non valido, ma cosa puoi fare se è troppo lungo? Il solito modo di usare una chiave basata su materiale più lungo della dimensione della chiave è ... applicare una funzione di hash (accettando una lunghezza di input arbitraria) al materiale.
Se vuoi ricavare una funzione hash da un algoritmo di crittografia, c'è in realtà un modo più semplice: invece di Hash (P) = Encrypt (P, P), definisci Hash (P) = Encrypt (P, 0), cioè crittografare un blocco di testo in chiaro a zero zeri (o qualche altro blocco di testo in chiaro noto). Questo è ciò che funzione di hashing della password Unix originale ha . Il vantaggio di questo approccio rispetto a Encrypt (P, P) è che è possibile trarre vantaggio dalle analisi esistenti dell'algoritmo: gli algoritmi di crittografia sono progettati per resistere agli attacchi con testo in chiaro. La limitazione con la password e la dimensione del sale rimane.