2009-08-31 4 views
17

Je travaille sur une fonctionnalité de chiffrement basé sur les classes héritées de SymmetricAlgorithm tels que TRIPLEDES, DES, etc.PasswordDeriveBytes vs Rfc2898DeriveBytes, obsolète, mais de façon plus rapide

Fondamentalement, il sont deux options pour générer la clé cohérente et IV ma classe d'algorithme, PasswordDeriveBytes et Rfc2898DeriveBytes, héritent tous les deux de la classe abstraite DeriveBytes.

La méthode PasswordDeriveBytes.GetBytes() est marquée comme obsolète dans le framework .NET alors que Rfc2898DeriveBytes.GetBytes() est recommandée car elle correspond à la norme PBKDF2. Cependant, en fonction de mes tests, l'appel de la même méthode GetBytes() dans la classe Rfc2898DeriveBytes est presque 15 fois plus lent que celui de la classe PasswordDeriveBytes, ce qui entraîne une utilisation inattendue du processeur (toujours supérieure à 50%).

certaines données Here're test:

  • : 100 Iterations
  • Type algorithme: DES
  • Texte original: "Je suis une clé de test, me chiffrer s'il vous plaît"
  • Heure:
    • PasswordDeriveBytes: 99ms
    • Rfc2898DeriveBytes: 1,373ms

D'après les tests, la mauvaise performance de Rfc2898DeriveBytes n'est pas acceptable dans un environnement de production.

Quelqu'un a-t-il déjà remarqué ce problème? Toute solution que je peux encore utiliser un standard sans atteindre la performance? Risque d'utiliser une méthode obsolète (pourrait être supprimé dans la future version)?

Merci les gars!

Edit:

Probablement que je trouve où le problème est ... Le nombre de comptage par défaut itération pour PasswordDeriveBytes est de 100, alors que pour Rfc2898DeriveBytes est 1000. Après avoir changé les au même numéro que 1000, l'exécution Rfc2898DeriveBytes est seulement le double temps.

+0

À quelle fréquence allez-vous dériver des clés dans un environnement de production? Et, en ce qui concerne vos données de synchronisation, lorsque vous avez dit "100 itérations" - est-ce itérations sur la clé onee, ou avez-vous généré 100 clés. Toutes les données de performance basées sur 100 essais sont suspectes, mais je pense que vous avez effectivement testé un essai. Comme dans tous les cas d'analyse de performances, il est tout simplement inapproprié de tirer des conclusions sur les performances du serveur en fonction du temps de réponse d'un seul essai. – Cheeso

+0

@Cheeso Le test était juste un test unitaire de la performance pour ces deux classes et il n'a pas été fait dans une vraie application. Les "100 itérations" que j'ai mentionnées étaient un peu confuses, cela signifie seulement que j'ai exécuté chacune d'elles 100 fois. Ce n'est pas un vrai test de perf, mais juste une comparaison. – tshao

+5

Je pense que vous avez peut-être manqué le point 'Rfc2898DeriveBytes' est fondamentalement _designed_ pour être lent afin que les vérifications de hachage de mot de passe (faites par ouverture de session et donc assez rarement) ne remarquent pas la performance touchée par les attaques par force brute. Si vous avez besoin de générer des hachages, 'Rfc2898DeriveBytes' n'est pas pour vous, mais si vous avez besoin d'une certaine sécurité des attaques par force brute, c'est. – Keith

Répondre

25

Ils ne sont pas la même chose.

Rfc2898DeriveBytes est une implémentation de PBKDF2. PasswordDeriveBytes est une implémentation de PBKDF1. PBKDF2 génère une sortie différente, en utilisant une méthode différente, et un nombre beaucoup plus important de rounds que PBKDF1.

Les fonctions de hachage de mot de passe, telles que celles-ci, qui sont utilisées pour la dérivation de clé sont supposées être lentes. C'est le point - cela les rend beaucoup plus difficiles à casser.

Les deux fonctions ne sont pas compatibles et PasswordDeriveBytes n'est pas aussi sécurisé.

+0

Merci BlackAura. Je peux comprendre que l'implémentation de PBKDF2 doit être lente, mais n'y a-t-il pas de meilleure pratique pour utiliser la classe Rfc2989DeriveBytes, par exemple comment mettre en cache/réutiliser la même clé/IV? L'exécution d'une méthode plusieurs fois aussi lente que dans un environnement de production n'est pas acceptable. : P – tshao

+4

Généralement, vous souhaitez uniquement utiliser ces fonctions pour générer une clé à partir d'un mot de passe. Habituellement pour quelque chose comme une archive protégée par mot de passe, ou similaire. Pour créer une archive, vous générez une IV aléatoire et générez une clé à partir du mot de passe et de l'IV. Vous stockez le IV (mais jamais la clé). Vous pouvez ensuite réutiliser la clé pour chaque fichier de l'archive, à condition que chaque fichier soit chiffré avec un IV différent (également stocké dans l'archive). La seule autre utilisation de ces fonctions est le hachage de mot de passe. Vous le feriez une fois, lorsqu'un utilisateur se connecte. Pour toute autre utilisation, il existe probablement un meilleur moyen. – BlackAura

9

Je pense qu'il vous manque le point de derivebytes. C'est censé être lent. Il utilise intentionnellement un algorithme lent qui ne peut pas être accéléré par une astuce intelligente.Le paramètre type "nombre d'itérations" doit être compris entre 2^16-2^20 et introduire un délai de 0,1-0,5 seconde entre l'entrée du mot de passe par l'utilisateur et la génération de la clé. L'intention est de se défendre contre les mots de passe faibles sélectionnés par les "utilisateurs ignorants paresseux" et de ralentir la recherche de force brute.

Questions connexes