Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Password Hashing in MySQL

Come avviene la gestione delle password in un database MySQL: dall'archiviazione delle parole chiave all'accesso degli utenti
Come avviene la gestione delle password in un database MySQL: dall'archiviazione delle parole chiave all'accesso degli utenti
Link copiato negli appunti

Come è noto, per l'accesso in connessione a MySQL sono necessarie una username e una password; entrambi questi dati sono conservati in una tabella, denominata user, del database chiamato mysql. Mentre il dato relativo alla username è inserito "in chiaro" all'interno della tabella, quello relativo alla password subisce invece un processo di codifica (hashing) tramite la funzione PASSWORD(); il DBMS "vedrà" la password nella sua forma codificata, l'utente invece la utilizzerà nel formato in cui l'ha scelta.

Per fare un esempio, la password "password" potrà essere vista da MySQL come "5d2e19393cc5ef67". La forma codificata rappresenta la password "reale", mentre quella utilizzata dall'utente è soltanto una stringa da passare come parametro al processo di codifica.

Password hashing e connessione

Quindi, nel momento in cui si cerca di stabilire una connessione, il DBMS riceve come input una stringa che viene sottoposta a codifica e poi confrontata con i valori dei records archiviati nel campo "password" della tabella "user".

Una volta stabilita la connessione, sarà possibile modificare il valore corrispondente al campo "password" utilizzando la funzione PASSWORD(), il comando SET PASSWORD() o in alternativa GRANT; ma questo sarà possibile soltanto se l'utente potrà vantare sufficienti privilegi.

Riassumendo, possiamo dire che il DBMS utilizza parole chiave codificate durante il processo di connessione richiesto da un terminale, mentre genera parole chiave codificate quando dal terminale viene inviato un input contenente una chiamata della funzione PASSWORD() o un comando SQL come SET PASSWORD() o GRANT.

Il processo di codifica delle password in MySQL è stato modificato è reso più sicuro a partire dalla versione 4.1 del DBMS; questo aggiornamento ha però creato alcuni problemi di "compatibilità verso l'alto", infatti, se da una parte le versioni 4.1 e superiori non presentano difficoltà nella connessione a server più datati, dall'altra sono stati riscontrati alcuni problemi per client MySQL precedenti alla 4.1 nella connessione a server più recenti. Per fare un esempio, provando a connettersi da un client 3.23 (versione ancora largamente diffusa) verso un server 5.0 si riceverà plausibilmente in output una notifica del genere: Client does not support authentication protocol requested by server; consider upgrading MySQL client.

Nelle versioni precedenti alla 4.1, la codifica delle password tramite l'apposita funzione per l'hashing delle stringhe produceva output della lunghezza massima di 16 bytes, per cui le risultanti della codifica erano pari a stringhe di 16 caratteri:

mysql> SELECT PASSWORD('albero');
+--------------------+
| PASSWORD('albero') |
+--------------------+
| 0bb5355b56b4c6cb   |
+--------------------+

A causa di questa impostazione anche la relativa colonna della tabella "user" era impostata per contenere un massimo di 16 caratteri (varchar(16)) per un tipo di dato stringa.

Con l'avvento della versione 4.1 la colonna "password" ha continuato ad ospitare anche stringhe della lunghezza di 16 caratteri, ma la funzione PASSWORD() è stata migliorata fino a riuscire a produrre output della lunghezza di 41 bytes:

mysql> SELECT PASSWORD('albero');
+-------------------------------------------+
| PASSWORD('albero')                        |
+-------------------------------------------+
| *7D69DA9FAAC2BF8B8181DCABB4E38B9DA1916389 |
+-------------------------------------------+

Va da sé che per sfruttare a pieno le nuove potenzialità della funzione PASSWORD() è necessario che il dato relativo alla parola chiave sia archiviato in una colonna che supporti l'inserimento di records della lunghezza di 41 bytes (varchar(41)).

La modifica alla lunghezza del campo "password" è stata introdotta di default nella versione 5.0 di MySQL, quindi nel caso di una installazione ex novo questa distribuzione creerà automaticamente un campo "password" in grado di archiviare stringhe da 41 bytes; nel caso invece si voglia operare un upgrade questo dovrà essere differente a seconda dei casi e delle versioni utilizzate, infatti mentre le versioni 4.1 e successive supportano il medesimo sistema di password hashing della 5.0, quelle precedenti si basano su un meccanismo più obsoleto.

Sarà quindi necessario aggiornare le versioni più datate prima alla 4.1 (o 4.1.x), per poi effettuare un ulteriore aggiornamento alla versione 5.0.

Lunghezza e caratteristiche delle password

Le modifiche che hanno coinvolto il meccanismo riguardante la generazione delle chiavi di accesso in MySQL, passando dalle versioni 3 attraverso le 4 fino alle recenti numero 5 del DBMS, non hanno riguardato soltanto la lunghezza delle password ma anche sostanziali modifiche nel formato di queste ultime.

I nuovi output della funzione PASSWORD sono preceduti, per esempio, dal carattere "*", caratteristica mancante nelle versioni più datate. Ma le novità non si limitano a questo semplice particolare, infatti MySQL non è solo in grado di generare password più lunghe ma anche di interpretarle e riconoscerle durante il processo di autenticazione con indubbi vantaggi dal punto di vista della sicurezza dei dati.

D'altra parte, anche l'incremento nella lunghezza della colonna deputata all'archiviazione ha la sua importanza: una colonna in grado di contenere stringhe di dimensioni ridotte permetterà unicamente autenticazioni basate sul primo tipo di hashing. Colonne in grado di ospitare valori più vasti permetteranno autenticazioni basate sia su stringhe più corte che su stringhe più lunghe.

Per questa ragione, le versioni di MySQL precedenti alla 4.1 possono autenticare l'accesso di client basati sull'hashing a 16 caratteri, quelle successive consentono autenticazioni con parole chiave prodotte sia da hashing a 16 caratteri sia da hashing a 41 caratteri. L'utilizzo di versioni più recenti si rivela quindi maggiormente flessibile anche per quanti riguarda le operazioni di modifica delle password.

La lunghezza consentita per gli hash di output, così come il meccanismo stesso alla base della generazione di questi ultimi, sono determinati da due elementi: il numero di caratteri consentito dalla colonna "password" e l'opzione --old-passwords.

La colonna "password" deve essere in grado di archiviare stringhe di almeno 41 bytes, nel caso in cui ciò non sia vero il DBMS notificherà l'impossibilità di memorizzare dati che vanno oltre la lunghezza di 16 bytes all'interno della tabella. Questa limitazione coinvolgerà sia la funzione PASSWORD() che i comandi SQL SET PASSWORD e GRANT. Questa situazione può presentarsi anche se si utilizzano versioni come la 4.1 o superiori in seguito ad un upgrade, ma non si è lanciato lo script di aggiornamento mysql_fix_privilege_tables deputato all'ampliamento della colonna.

Una volta accertata la possibilità di archiviare dati fino a 41 bytes, questi potrebbero non essere ancora accettati in tabella anche nelle versioni più recenti di MySQL. Ciò accade perché in alcuni casi la direttiva --old-passwords è ancora impostata a ON e non permette fino a modifica il supporto di stringhe di dimensioni superiori ai 16 caratteri.

Hash corti o hash lunghi?

L'impostazione su ON dell'opzione --old-passwords è utilizzato per questioni di compatibilità con le vecchie versioni del DBMS. In effetti questa configurazione non crea problemi ai fini dell'autenticazione e possono essere utilizzati senza problemi hash di lunghezza pari a 16 o 41 bytes, ma di fatto impedisce la creazione e l'archiviazione di nuove chiavi in seguito alla modifica di quelle già presenti, che non potrebbero più essere utilizzate per la connessione a versioni datate di MySQL.

In pratica modificando una password da 16 a 41 bytes potrebbe verificarsi un caso simile al seguente: un client dotato di una versione non aggiornata del DBMS, mettiamo la 3.23, si connette attraverso una username a cui è associata come password una stringa da 16 caratteri e il relativo account ha sufficienti privilegi per poter modificare la propria chiave d'accesso; forte dei privilegi assegnati, l'account decide di modificare la sua password, ma la direttiva --old-passwords non è impostata su ON; MySQL raccoglie la nuova password dell'utente e la converte attraverso il meccanismo di hashing più recente, viene quindi prodotta una stringa della lunghezza di 41 bytes.

Il risultato sarà che il client non potrà più connettersi allo stesso account, infatti ora a quest'ultimo è associata una chiave d'accesso che non può essere gestita e quindi non verrà riconosciuta in fase di autenticazione.

Quindi l'abilitazione o meno della direttiva --old-passwords si presenta come un'arma a doppio taglio: da una parte configurarla su ON non consente la creazione di stringhe codificate della massima lunghezza, ciò si rivela un problema dal punto di vista della sicurezza (meno lavoro per chi tenta di decifrare le chiavi di accesso); dall'altra l'impostazione su OFF non consente la modifica di password per account relativi a vecchi client che saranno quindi maggiormente esposti a indebiti tentativi di accesso ai dati.

Fortunatamente è possibile risolvere questo problema "dall'interno", sfruttando nel modo adeguato i comandi SQL a disposizione. Normalmente infatti utilizzeremmo il comando SET PASSWORD in questo modo:

SET PASSWORD FOR 'nome_utente'@'nome_host' = PASSWORD('password');

È possibile però introdurre direttamente l'opzione --old-passwords attraverso l'omologa funzione OLD_PASSWORD()

SET PASSWORD FOR 'nome_utente'@'nome_host' = OLD_PASSWORD('password');

In questo modo sarà possibile produrre hash della lunghezza di 16 bytes anche quando l'opzione --old-passwords è impostata in OFF

Ti consigliamo anche