web-dev-qa-db-fra.com

Comment hacher des mots de passe dans postgresql?

J'ai besoin de hacher certains mots de passe avec du sel sur postgresql, et je n'ai pas pu trouver de documentation pertinente sur la façon de le faire.

Alors, comment puis-je hacher les mots de passe (avec certains sels) dans postgresql?

46
Kzqai

Cela fait un moment que je n'ai pas posé cette question, et je connais beaucoup mieux la théorie cryptographique maintenant, voici donc l'approche la plus moderne:

Raisonnement

  • N'utilisez pas md5. N'utilisez pas un seul cycle de hachage rapide de la famille sha. Les hachages rapides aident les attaquants, vous ne voulez donc pas cela.
  • Utilisez à la place un hachage gourmand en ressources, comme bcrypt. Bcrypt est testé dans le temps et évolue pour être évolutif.
  • Ne vous embêtez pas à rouler votre propre sel, vous pourriez bousiller votre propre sécurité ou portabilité, compter sur gen_salt () pour générer ses propres sels uniques à chaque utilisation.
  • En général, ne soyez pas idiot, n'essayez pas d'écrire votre propre crypto maison, utilisez simplement ce que les gens intelligents ont fourni.

Packages d'installation Debian/Ubuntu

Sudo apt-get install postgresql   // (of course)
Sudo apt-get install postgresql-contrib libpq-dev   // (gets bcrypt, crypt() and gen_salt())
Sudo apt-get install php5-pgsql   // (optional if you're using postgresql with php)

Activez crypt () et bcrypt dans postgresql dans votre base de données

// Create your database first, then:
cd `pg_config --sharedir` // Move to the postgres directory that holds these scripts.
echo "create extension pgcrypto" | psql -d yOuRdATaBaSeNaMe // enable the pgcrypo extension

Utilisez crypt () et gen_salt () dans les requêtes

Comparer: passer au hachage existant avec:

select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)

Créez un hachage de: mot de passe avec un excellent sel aléatoire:

insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)

Le hachage bcrypt à partir de Php est légèrement préférable

Il existe des fonctions password_* En php 5.5 et supérieur qui permettent un hachage de mot de passe trivialement simple avec bcrypt (il est temps!), Et il existe une bibliothèque de compatibilité descendante pour les versions inférieures. Généralement ce hachage revient à encapsuler un appel système linux pour une utilisation moindre du CPU, bien que vous souhaitiez peut-être vous assurer qu'il est installé sur votre serveur. Voir: https://github.com/ircmaxell/password_compat (nécessite php 5.3.7+)

Attention à la journalisation

Notez qu'avec pg_crypto, les mots de passe sont en texte clair tout au long de la transmission du navigateur, vers php, vers la base de données. Cela signifie qu'ils peuvent être enregistrés en texte clair à partir des requêtes si vous ne faites pas attention à vos journaux de base de données. par exemple. avoir un journal des requêtes lentes postgresql pourrait intercepter et enregistrer le mot de passe d'une requête de connexion en cours.

En résumé

Utilisez php bcrypt si vous le pouvez, cela réduira le temps que le mot de passe reste non haché. Essayez de vous assurer que votre système Linux a installé bcrypt dans sa crypt() pour que ce soit performant. La mise à niveau vers au moins php 5.3.7+ est fortement recommandée car l'implémentation de php est légèrement boguée de php 5.3.0 à 5.3.6.9, et retombe de manière inappropriée sur le DES cassé sans avertissement dans php 5.2.9 et inférieur .

Si vous voulez/avez besoin d'un hachage post-gres, l'installation de bcrypt est la voie à suivre, car les hachages installés par défaut sont anciens et cassés (md5, etc.).

Voici des références pour plus de lecture sur le sujet:

75
Kzqai

Une application doit hacher ses mots de passe en utilisant une fonction de dérivation de clé comme bcrypt ou pbkdf2. Voici plus d'informations sur le stockage sécurisé des mots de passe .

... mais parfois vous avez toujours besoin de fonctions cryptogrpahiques dans une base de données.

Vous pouvez utiliser pgcrypto pour accéder à sha256 qui est membre de la famille sha2. Gardez à l'esprit que sha0, sha1 md4 et md5 sont très cassés et ne doivent jamais être utilisés pour les hachages de mot de passe.

Ce qui suit est une bonne méthode de hachage des mots de passe:

digest("salt"||"password"||primary_key, "sha256")

Le sel doit être une grande valeur générée aléatoirement. Ce sel doit être protégé, car les hachures ne peuvent pas être brisées jusqu'à ce que le sel soit récupéré. Si vous stockez le sel dans la base de données, il peut être obtenu avec le hachage du mot de passe à l'aide de l'injection sql. La concaténation de la clé primaire est utilisée pour empêcher 2 personnes d'avoir le même hachage de mot de passe même si elles ont le même mot de passe. Bien sûr, ce système pourrait être amélioré, mais c'est beaucoup mieux que la plupart des systèmes que j'ai vus.

En général, il est préférable de hacher votre application avant qu'elle n'atteigne la base de données. En effet, les requêtes peuvent apparaître dans les journaux, et si le serveur de base de données appartenait, elles pourraient activer la journalisation pour obtenir des mots de passe en texte clair.

16
rook

Exemples et documentation sur: http://www.postgresql.org/docs/8.3/static/pgcrypto.html

UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));

SELECT pswhash = crypt('entered password', pswhash) FROM ... ;
8
Matej Puntar