web-dev-qa-db-fra.com

Rfc2898DeriveBytes utilisant HMAC SHA1 est-il toujours considéré comme "suffisamment sécurisé" pour le hachage des mots de passe?

Un CISSP m'a dit que la classe .NET Rfc2898DeriveBytes ne passerait pas un audit de sécurité aujourd'hui car elle utilise toujours SHA1. Sa dépendance à SHA1 - même avec les itérations - le rend trop vulnérable au craquage par force brute. Pour ma propre compréhension et pour quiconque tombe sur cette question, est-ce que Rfc2898DeriveBytes est toujours considéré comme une méthode sécurisée pour hacher les mots de passe? Dans le même ordre d'idées, le HMAC SHA256 avec un sel mais pas d'itérations est-il suffisant?

Pour mémoire, puisque j'ai été mandaté pour utiliser autre chose que Rfc2898DeriveBytes et que je sais mieux que de rouler le mien à partir de zéro, j'ai l'intention de démonter Rfc2898DeriveBytes et de dupliquer le code en utilisant SHA256 au lieu de SHA1.

22
TheOtherTimDuncan

Rfc2898DeriveBytes implémente l'algorithme standard connu sous le nom PBKDF2 et défini dans RFC 2898 (d'où le nom). Cet algorithme utilise une fonction pseudo-aléatoire sous-jacente configurable, qui est généralement HMAC , et HMAC lui-même s'appuie sur une fonction de hachage sous-jacente configurable, généralement SHA-1. Bien que tout cela soit configurable, une implémentation donnée peut ne pas être aussi flexible et, en fait, Rfc2898DeriveBytes toujours utilise HMAC et toujours utilise SHA-1 comme fonction sous-jacente pour SHA-1.

De nos jours, les personnes appelées collectivement "auditeurs" ont tendance à gémir, à pleurnicher, à crier, à se moquer et à tourner en rond quand elles voient tout ce qui implique SHA-1 . C'est scientifiquement injustifié. À l'heure actuelle , parmi toutes les publications scientifiques, rien n'indique que SHA-1 lorsqu'il est utilisé dans HMAC serait faible. Les faiblesses connues de SHA-1 sont d'environ collisions qui n'ont pas d'impact sur HMAC (et elles sont toujours théoriques de toute façon). Si un gars avec un CISSP insiste sur le fait que SHA-1 rend réellement PBKDF2 plus vulnérable à la force brute, alors ce type devrait aller réapprendre ses leçons.

Néanmoins, le changement de SHA-256 n'est pas une mauvaise idée, donc si éviter SHA-1 est ce qu'il faut pour se débarrasser des auditeurs, tant pis.

Cependant, il faut encore dire ce qui suit:

  • Le démontage puis la modification est une méthode assez grossière et tend à conduire à un code non maintenable. Vous pouvez simplement commencer à partir du code source réel (par exemple à partir de ici ), ou, plus simplement (et avec un statut juridique plus propre), le réimplémenter à partir de zéro. .NET fournit un implémentation HMAC/SHA-256 ; l'utiliser pour faire un code PBKDF2 n'est pas difficile.

  • Alternativement, vous pouvez essayer de réutiliser une autre implémentation existante, comme celle-ci .

  • Vous utilisez PBKDF2 lorsque vous souhaitez "hacher un mot de passe", et toutes les fonctions ne sont pas égales à cet égard. Une fonction de hachage n'est utile que dans la mesure où elle coûte cher aux attaquants. À cet égard, PBKDF2 avec SHA-1 ou SHA-256 n'est pas le meilleur choix; sans doute, PBKDF2 avec SHA-512 est une meilleure affaire (car les GPU existants ont plus de mal à optimiser SHA-512 que SHA-256), mais d'autres solutions peuvent être préférables, en particulier bcrypt . Pour en savoir plus sur ce sujet, lisez this , et plus généralement this .

    Cela signifie que même si les "faiblesses" de SHA-1 n'affaiblissent pas PBKDF2, il s'agit toujours d'une fonction qui peut être très bien optimisée sur le GPU, ce qui est, dans ce cas, un problème - mais, et c'est le point important ici, SHA-256 ne fait pas mieux.

  • Dans tous les cas, en utilisant une implémentation C # pure, vous acceptez que cette opération spécifiquement gourmande en CPU s'exécute avec le ralentissement inhérent de cette technologie, qui peut être estimé à un facteur de 2 à 3 par rapport au code C optimisé (ou Assembly) . En d'autres termes, vous donnez un avantage de 2x ou 3x aux attaquants. Par conséquent, vous voudrez peut-être utiliser du code natif ici, pas du C # pur.

25
Thomas Pornin