2016-07-22 1 views
4

J'ai été chargé d'écrire une nouvelle méthode pour le calcul des hachages de mots de passe pour remplacer l'ancien qui ne nous semble pas encore suffisamment sécurisé. Il y a quelque temps, j'ai lu le livre Security Driven .NET, dans lequel j'ai appris que l'important est d'utiliser un algorithme avec un nombre configurable de révolutions (par opposition à un simple hachage), et que dans .NET, la recommandation était appelé PBKDF2 pour la gestion des mots de passe. Je lis aussi que comme une amélioration à la façon dont ASP.NET traite les mots de passe, il serait bien si le hachage résultant stocké dans la base de données était cryptographiquement lié à l'utilisateur (nom ou identifiant) en utilisant le PBKDF2 pour créer un master clé, puis utilisez le nom d'utilisateur (ou id) pour créer une clé dérivée en utilisant HKDF. Mais encore une fois, c'est une connaissance superficielle que je lis d'un livre auquel je n'ai pas actuellement accès, donc je ne peux pas revérifier si ma mémoire est correcte.Le hachage de mot de passe à l'aide de PBKDF2 et HKDF dans .NET

De plus, je n'ai jamais utilisé les API DerivedBytes .NET auparavant, donc je peux me tromper. Ma question est la suivante: est-ce que je fais les choses correctement dans le code suivant? Est-ce que j'utilise les API correctement? Et cette implémentation est-elle "suffisamment sécurisée"? Ou est-ce que je fais quelque chose de mal qui supprime complètement toute la sécurité?

protected override byte[] ComputeHash(string user, string salt, string password) 
{ 
    var userBytes = user.ToBytes(); 
​ 
    using (var pbkdf2 = new PBKDF2(MacFactories.HMACSHA512, password.ToBytes(), salt.ToBytes())) 
    { 
     var masterKey = pbkdf2.GetBytes(128); 
     using (var hkdf = new HKDF(MacFactories.HMACSHA512, masterKey, userBytes, userBytes)) 
     { 
      return hkdf.GetBytes(64); 
     } 
    } 
} 

Répondre

4

Vous avez l'idée correcte/approche - ici est une mise en œuvre un peu mieux:

byte[] ComputeHash(string user, string salt, string password) 
{ 
    using (var pbkdf2 = new PBKDF2(HMACFactories.HMACSHA512, password, salt.ToBytes())) 
    using (var hkdf = new HKDF(HMACFactories.HMACSHA512, pbkdf2.GetBytes(64), user.ToBytes())) 
     return hkdf.GetBytes(64); 
} 

Vous ne devriez pas demander pbkdf2 pour plus d'octets que l'octet longueur du PRF sous-jacente (dans votre cas , SHA512 qui produit 64 octets).

Vous pouvez laisser le contexte hkdf comme null puisque vous ne semblez pas en avoir besoin.

Pour d'autres qui pourraient se demander quelle bibliothèque utilise le code ci-dessus - Inferno crypto.