web-dev-qa-db-fra.com

Avec PBKDF2, quelle est la taille de hachage optimale en octets? Et la taille du sel?

Lors de la création d'un hachage avec PBKDF2, cela permet au développeur de choisir la taille du hachage. Est-ce toujours mieux? Et la taille du sel aléatoire? Cela devrait-il être de la même taille que le hachage?

EDIT: Particulièrement dans le hachage des mots de passe.

27
blesh

Pour la fonction de hachage, vous souhaitez utiliser une fonction pour laquelle le type de plate-forme le plus efficace (celui qui produira le plus de calculs de hachage par seconde et par dollar) est la machine que vous avez l'intention d'utiliser (c'est-à-dire un PC). C'est parce que vous êtes dans une course aux armes avec l'attaquant, et l'attaquant peut acheter d'autres types de matériel pour obtenir un Edge sur vous (comme un GPU). Les GPU sont très bons en arithmétique 32 bits, mais pas en arithmétique 64 bits, alors qu'un PC (en mode 64 bits) sera assez rapide dans ce dernier cas.

Ainsi, utilisez une fonction de hachage qui s'exécute sur des opérations arithmétiques 64 bits. Cela pointe vers SHA-512 .

PBKDF2 est une fonction de dérivation de clé : il produit une sortie de taille configurable. Pour le hachage de mot de passe, vous voulez que la taille soit suffisamment grande pour dissuader les attaques de pré-image génériques (c'est-à-dire essayer des mots de passe aléatoires jusqu'à ce qu'une correspondance soit trouvée), donc cela nécessiterait, par exemple, au moins 80 bits de sortie. Ne serait-ce que pour rendre la sécurité plus convaincante pour les imprudents, et aussi pour l'esthétique, optez pour la prochaine puissance de 2: une sortie 128 bits . Il n'est pas utile d'aller plus loin.

Le sel doit être unique - aussi unique que possible. Un moyen facile d'atteindre des valeurs de sel uniques est de générer des sels avec un PRNG cryptographiquement fort : la probabilité de réutiliser une valeur de sel sera suffisamment faible pour être négligée si ces sels aléatoires sont suffisamment gros et "assez grands" "signifie" 128 bits ". Utilisez donc des sels aléatoires de 128 bits .

Personnellement, je préfère bcrypt plutôt que PBKDF2 pour le hachage de mot de passe.

24
Thomas Pornin

Selon la norme PBKDF2, la taille minimale recommandée pour le sel est de 64 bits, bien que je recommande personnellement 128 bits ou plus pour une marge de sécurité décente. La taille du sel est indépendante de votre choix de hachage.

En ce qui concerne la sécurité, je recommande de choisir une longueur de clé dérivée de au moins de la même taille que la sortie de votre sel, avec un minimum de 256 bits. De toute façon, toute taille de hachage inférieure à 256 bits est inférieure à la limite de sécurité de la plupart des fonctions de hachage modernes.

Choisir une longueur de clé dérivée inférieure à la longueur de sortie de la fonction de hachage n'a pas de sens, sauf si vous utilisez la clé pour un chiffrement de bloc qui ne peut pas gérer une clé de cette taille.

En termes de sécurité optimale, je suggère SHA-512 comme PRF, avec une clé dérivée de 512 bits, un sel de 128 bits et autant d'itérations que votre situation peut le justifier.

11
Polynomial

Dans le cas où votre plate-forme de choix est .NET, il existe un article OWASP spécifiquement dédié à sa classe Rfc2898DeriveBytes . Notez spécifiquement (soulignement le mien):

L'implémentation .NET intégrée de Rfc2898DeriveBytes limite l'utilisateur à une fonction psudorandom - HMAC avec SHA-1 . Ceci est acceptable dans la plupart des scénarios aujourd'hui, mais à l'avenir, une fonction de hachage plus complexe peut être requise.

En utilisant PBKDF2 pour le stockage des mots de passe, il ne faut jamais sortir plus de bits que la taille de la fonction de hachage de base. Avec PBKDF2-SHA1, cela représente 160 bits ou 20 octets . Produire plus de bits ne rend pas le hachage plus sûr, mais cela coûte beaucoup plus de temps au défenseur sans coûter à l'attaquant. Un attaquant comparera simplement la première sortie de la taille de la fonction de hachage, ce qui lui fera gagner du temps pour générer la réinitialisation de la sortie PBKDF2.

Ils ont également un exemple de code, que j'ai ajusté selon les conseils des autres réponses:

public static string Hash(string str)
{
    // Generate the hash, with an automatic 16 byte salt
    using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(str, 16))
    {
        rfc2898DeriveBytes .IterationCount = 10000 // or whatever you can afford
        byte[] hash = rfc2898DeriveBytes.GetBytes(20);
        byte[] salt = rfc2898DeriveBytes.Salt;
        return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
    }
}
4
Ohad Schneider