Question:
Pourquoi improviser votre propre fonction de hachage à partir des fonctions de hachage existantes est si mauvais
George Powell
2013-04-01 06:24:02 UTC
view on stackexchange narkive permalink

J'ai bien peur de me faire jeter des tomates sur moi pour avoir posé cette vieille question, mais voilà.

Après avoir lu qu'il est dangereux de créer votre propre hachage de mot de passe à partir des fonctions de hachage existantes plus de et plus de à nouveau, je ne comprends toujours pas la logique. Voici quelques exemples:

  • md5 (md5 (sel) + bcrypt (mot de passe))
  • scrypt (bcrypt (mot de passe + salt))
  • sha1 (md5 (scrypt (mot de passe + md5 (sel))))

Les arguments typiques contre ceux-ci vont comme suit:

Vous n'êtes pas un cryptographe! Vous ne savez pas si ces hachages sont plus sécurisés. Laissez-le aux experts qui savent ce qu'ils font. Ceux-ci n'ajoutent aucune sécurité supplémentaire.

Certes, ils n'améliorent pas la fonction en tant que hachage (c'est-à-dire rendent plus difficile l'inversion ou la recherche de collisions, etc.), mais Certainement sûrement ils ne le font pas pire comme hachage? S'ils le faisaient, les pirates pourraient alors hacher à nouveau les mots de passe hachés standard dans ces hachages farfelus comme ils l'entendent et affaiblir le hachage? Je ne l'achète pas.

Deuxième argument:

Principe de Kerckoffs: Un cryptosystème doit être sécurisé même si tout ce qui concerne le système est connu.

D'accord. C'est essentiellement la raison pour laquelle vous ne stockez pas vos mots de passe en texte brut. Mais si ma réponse à la première critique tient, alors ces hachages farfelus fonctionnent toujours comme des hachages sécurisés, et notre système ne rompt pas le principe de Kerckoffs plus qu'il ne le ferait avec un hachage standard.

Voici deux avantages possibles (et intéressants, pour autant que je sache) à utiliser un hachage "farfelu" sur un hachage normal:

  1. Bien sûr, votre système doit être sécurisé si l'attaquant possède le code source, mais il est très probable que votre attaquant n'aura pas accès à votre code source et probablement ne sera pas en mesure de deviner votre hachage farfelu, rendant toute tentative de force brute impossible.
  2. (Celui-ci est la vraie motivation derrière moi en posant cette question) BCrypt est pensé pour être sûr, dur pour le CPU et le GPU (super) mais peut être très rapide avec du matériel spécialisé. On dit que SCrypt est difficile à forcer brutalement sur les CPU, les GPU et actuellement disponible spécialisé, mais il est plus récent et ne fait pas autant confiance à la communauté cryptographique que BCrypt en raison du manque d'exposition dont il dispose. Mais le hachage BCrypt (SCrypt (password + salt)) n'obtient-il pas le meilleur des deux mondes?

J'apprécie que la passion / colère derrière la plupart des diatribes contre ces hachages maison vient du manque de connaissances du programmeur moyen sur ce qui fait un bon hachage, et d'une inquiétude qui encourage ce genre de wacky-hashing se terminera inévitablement par des hachages faibles et inutiles dans le code de production. Mais Si le hachage farfelu est soigneusement construit à partir de hachages solides et fiables, les gains de sécurité ne sont-ils pas très précieux et réels?


Mise à jour

J'ai eu un tas de bonnes réponses à ce sujet, merci. Ce que je semblais oublier dans mes hypothèses, c'est que, bien que la combinaison de hachages ne puisse pas faciliter le déchiffrage du mot de passe original et donc déchiffrer les hachages constituants, la combinaison de deux hachages sécurisés ou plus peut - au moins en principe - être plus faible que n'importe lequel de ses hachages internes en raison des interactions non étudiées et complexes entre eux. Cela signifie qu'il pourrait être possible de trouver une chaîne qui a dépassé le hachage farfelu sans nécessairement casser les hachages qui la composaient.

Si votre objectif est simplement de vous protéger contre un attaquant sans accès à votre code source, alors [en utilisant un poivre] (http://security.stackexchange.com/questions/21263/how-to-apply-a-pepper-correctly- to-bcrypt) (essentiellement une valeur secrète codée en dur que vous hachez avec le mot de passe) serait suffisante et moins sujette aux erreurs que de créer votre propre fonction de hachage.
pourquoi ne pas ajouter un `sleep (15000);` après chaque hachage? certains avantages sont inconnus mais cela ne le rend certainement pas moins sûr :)
Dix réponses:
Polynomial
2013-04-01 16:32:59 UTC
view on stackexchange narkive permalink

Le fait que vous ayez besoin de poser cette question est la réponse elle-même - vous ne savez pas ce qui ne va pas avec l'empilement de ces primitives, et par conséquent ne pouvez pas connaître les avantages ou des faiblesses.

Faisons une analyse sur chacun des exemples que vous avez donnés:

md5 (md5 (sel) + bcrypt (mot de passe))

Je peux voir quelques problèmes ici. Le premier est que vous êtes en train de faire du sel. Quel avantage cela donne-t-il? Aucun. Cela ajoute de la complexité, et le sel est simplement destiné à être unique pour éviter les collisions de mots de passe et les attaques de pré-calcul (par exemple, table arc-en-ciel). Utiliser MD5 ici n'a aucun sens, et pourrait en fait affaiblir le schéma puisque MD5 a connu des collisions insignifiantes. En tant que tel, il existe une petite possibilité que l'introduction de MD5 ici puisse signifier que deux sels uniques produisent le même hachage MD5, résultant en un sel effectivement dupliqué. C'est mauvais.

Ensuite, vous utilisez bcrypt sur le mot de passe. D'accord. Eh bien, la plupart des implémentations de bcrypt nécessitent un salt en interne, donc cela est déjà techniquement invalide. Disons que vous le savez, et que vous vouliez dire bcrypt (md5 (salt), mot de passe) . Cette partie tombe toujours à la faiblesse que j'ai décrite ci-dessus, mais ce n'est pas trop minable - supprimez le MD5 et c'est une utilisation standard de bcrypt.

Enfin, vous MD5 le tout. Pourquoi fais-tu ça? Quel est le but? Quel avantage cela apporte-t-il? Pour autant que je sache, il n'y a aucun avantage. Au détriment, cela ajoute plus de complexité. Puisque la plupart des implémentations de bcrypt utilisent la notation $ 2a $ rounds $ salt $ hash , vous allez devoir écrire du code pour analyser cela afin de pouvoir extraire la partie de hachage et stocker le reste séparément. Vous allez également avoir besoin d'une implémentation MD5, ce qui n'était pas nécessaire.

Donc, en termes d'empreinte de code pour les vecteurs d'attaque potentiels, vous êtes passé d'une simple implémentation de bcrypt à une implémentation de bcrypt avec un code d'analyse personnalisé et une implémentation MD5, et du code glue pour tout coller. Pour un bénéfice nul, et une vulnérabilité potentielle dans la gestion du sel.

Le suivant:

scrypt (bcrypt (mot de passe + sel))

Celui-ci n'est pas si mal, mais encore une fois, vous avez besoin d'un peu de code pour analyser les résultats de bcrypt en hash et salt / round count séparément. Dans ce cas, je suppose qu'il y a un léger avantage, car bcrypt et scrypt fonctionnent de manière différente pour à peu près le même objectif, ce qui le rendrait un peu plus difficile pour qu'un attaquant extrêmement bien financé crée des ASIC personnalisés pour casser votre plan. Mais est-ce vraiment nécessaire? Allez-vous vraiment vous retrouver dans une situation où un État-nation consacrera quelques millions de dollars simplement pour casser votre hachage? Et, si ce cas se présente, est-ce que cela dérangera vraiment l'attaquant de devoir dépenser quelques millions de plus pour doubler son nombre de puces?

Un autre problème potentiel avec la combinaison de bcrypt et de scrypt de cette manière est qu'il y a eu très peu d'étude sur la façon dont les deux interagissent. En tant que tel, nous ne savons pas s'il existe des cas étranges qui peuvent causer des problèmes. Comme exemple plus évident, prenez le pavé unique. Nous calculons c = m ^ k pour un message m et une clé parfaitement aléatoire également longue k , et nous obtenons une sécurité parfaite. Alors faisons-le deux fois , pour encore plus de sécurité! Cela nous donne c = m ^ k ^ k ... oh, attendez, cela nous donne juste m . Donc, parce que nous n'avons pas pris le temps de bien comprendre comment fonctionnaient les internes du système, nous nous sommes retrouvés avec une véritable vulnérabilité de sécurité. C'est évidemment plus compliqué dans le cas des KDF, mais le même principe s'applique.

Et enfin:

sha1 (md5 (scrypt (mot de passe + md5 (sel))) )

Encore une fois, nous rencontrons le problème du sel de MD5. Je suis également intrigué par MD5 en utilisant le hachage SHA1. Quel avantage cela pourrait-il avoir, si vous utilisez déjà un KDF lent comme scrypt? Les quelques nanosecondes qu'il faudrait pour calculer ces hachages sont pâles par rapport aux centaines de millisecondes qu'il faudrait pour calculer le résumé scrypt du mot de passe. Vous ajoutez de la complexité pour une couche de «sécurité» absolument hors de propos, ce qui est toujours une mauvaise chose. Chaque ligne de code que vous écrivez est une vulnérabilité potentielle.


Maintenant, souvenez-vous de ce que j'ai fait au début de ma réponse. Si, à un moment quelconque de cette réponse, vous pensiez "oh oui, je n'y ai pas pensé", alors mon argument est prouvé.

Vous rencontrez ce que je décrirais comme La fausse maxime de Dave:

Si j'ajoute plus de choses cryptographiques, ce sera plus sécurisé.

C'est un trait commun parmi développeurs, et je l'ai cru une fois aussi. Cela va de pair avec le déni d'autres principes, comme le Principe de Kerckhoff. En fin de compte, vous devez réaliser et accepter que l'obscurité n'est pas un rail de sécurité; c'est une béquille pour une crypto faible. Si votre crypto est forte, elle n'a pas besoin de béquille.

Bonne réponse. Je n'avais pas vraiment pensé au premier et au dernier exemple de hachage empilé. Ils ont un peu ruiné mon argument sans raison. J'étais plus intéressé par le hachage bcrypt - scrypt et si cela pourrait * éventuellement * être plus faible que scrypt / bcrypt seul.
L'interaction entre les deux n'est pas définie, car personne ne l'a étudiée. La combinaison des deux * pourrait * fournir plus de sécurité, mais cela * pourrait * également conduire à des interactions inhabituelles entre les éléments internes de ces hachages. Un bon exemple de ceci est le tampon unique. Le calcul de `c = m ^ k` vous donne un niveau de sécurité parfait lorsque` k` est vraiment aléatoire et inconnu de l'attaquant. Alors faisons-le deux fois, pour plus de sécurité! On se retrouve donc avec `c = m ^ k ^ k`, ce qui donne` m`. Oh, oups. Évidemment, les interactions sont plus complexes dans les hachages, mais le principe est toujours valable.
Ce que je veux dire, c'est que puisque nous ne savons pas quels problèmes potentiels pourraient exister, pourquoi ne pas suivre l'itinéraire sûr connu et utiliser simplement scrypt avec un facteur de travail décent? C'est plus que suffisamment sûr pour presque tous les usages.
@Polynomial +1 Excellente réponse. Cependant, je n'étais pas convaincu de la partie bcrypt / scrypt de votre réponse avant de lire votre commentaire sur les tampons à usage unique. Pourrait envisager d'ajouter ce commentaire à votre réponse.
@Phil Terminé. J'espère que cela a du sens.
"Un autre problème potentiel lié à la combinaison de bcrypt et de scrypt comme celui-ci est qu'il y a eu très peu d'études sur la façon dont les deux interagissent. En tant que tel, nous ne savons pas s'il existe des cas étranges pouvant causer des problèmes. Comme exemple plus évident, Prenons le pavé de temps unique. Nous calculons c = m ^ k pour un message m et une clé parfaitement aléatoire k également longue, et nous obtenons une sécurité parfaite. Alors faisons-le deux fois, pour encore plus de sécurité! " Vous le faites mal. Le truc `bcrypt (scrypt (x))` est correct alors que `xor (xor (x, k), k)` ne l'est pas parce qu'un `bcrypt` supplémentaire est quelque chose qu'un attaquant pourrait faire aussi.
@thejh C'était un exemple de la façon dont l'ignorance des éléments internes d'une opération peut conduire à des failles de sécurité. Ce n'était pas censé être une analogie directe, d'où la raison pour laquelle j'ai dit "De toute évidence, c'est plus compliqué dans le cas des KDF, mais le même principe s'applique."
Je ne vois toujours pas pourquoi la chose scrypt (bcrypt (x)) pourrait être un problème. Si les deux interagissent bizarrement, le simple fait d'utiliser bcrypt ne le rend pas plus sûr - un attaquant peut simplement scrypt () ce que vous avez bcrypt () 'd. De plus, si quelqu'un trouve un moyen plus intelligent de deviner le texte brut original pour un algorithme de hachage, il n'aura probablement pas simultanément un moyen plus rapide pour l'autre algorithme. Disons que les gens pensaient légitimement que ROT13 était un bon mécanisme de hachage. Si j'utilisais ROT13 (bcrypt (x)), ne serais-je toujours pas mieux loti quand les gens ont «craqué» ROT13?
Le problème principal est que vous devez introduire plus de code pour analyser la sortie codée de scrypt / bcrypt afin que le salt et le nombre d'arrondis puissent être stockés séparément. De plus, il n'offre pas vraiment de sécurité accrue - scrypt est plus que suffisant pour 99,9% des situations.
L'utilisation conjointe de scrypt et de bcrypt pose le problème qu'ils prennent tous les deux du temps à s'exécuter - vous finirez probablement par réduire de moitié le nombre de tours sur chacun pour compenser le fait de devoir exécuter les deux, ce qui est plus susceptible d'être non sécurisé qu'un scrypt «complet» au-dessus d'un bcrypt "complet" est.
Les attaquants d'@Brilliand: trouveront presque certainement des moyens d'accélérer les deux algorithmes au moins quelque peu - probablement par des quantités différentes. S'il s'avère que les attaquants trouvent une accélération de 100: 1 pour un algorithme et de 2: 1 pour l'autre, les attaquants obtiendraient une accélération d'environ 4: 1 contre un système qui utilisait chaque algorithme pendant la moitié du nombre de rounds que ce qui aurait pu être utilisé dans le absence de l'autre. À moins que l'on ne sache avec quel système les attaquants auraient «plus de chance», les paris de couverture ne semblent guère déraisonnables.
@Polynomial: J'ai posté une réponse simplifiée (sorte de résumé).Je ne sais pas si ma logique est correcte, donc si vous avez quelques minutes, pourriez-vous la vérifier / la modifier s'il vous plaît?Je pense que cela peut être utile.Merci d'avance!
@root: Cela leur donnera quelque chose comme scrypt (bcrypt (what_attacker_has)) = scrypt (bcrypt (real_password)), mais pas nécessairement tel que bcrypt (what_attacker_has) = scrypt (real_password).
@Polynomial, `m ^ k ^ k` n'est pas une bonne analogie.Qu'en est-il de `m ^ k ^ k2`?Je ne vois pas en quoi cela serait ** moins ** sécurisé.
@Ricky, ??Je pense que personne n'a compris ce que vous essayez de dire.
@Brilliand, La division du pourcentage de hachage sur différentes races d'algorithmes est en fait un avantage en raison des ** économies d'échelle **.Un attaquant qui pourrait produire en masse des disjoncteurs optimisés pour bcrypt pourrait ne pas être en mesure de produire en masse des disjoncteurs optimisés pour le scrypt.La même logique s'applique à tous les hachages de races différentes.
Un plus gros problème est que `sha1 (md5 (m))` pour toute valeur de `m` diminue les résultats possibles à 128 bits, bien que SHA-1 fournisse un condensé de 160 bits.Bien que ce ne soit probablement pas un gros problème car 128 c'est encore beaucoup, vous réduisez inutilement la taille du condensé.Prenons un exemple extrême, où vous avez «sha1 (crc8 (m))».Bien qu'un condensé SHA-1 soit de 128 bits, il n'y aura que 256 résultats possibles en raison du CRC 8 bits au milieu.En créant un goulot d'étranglement, vous réduisez la sécurité en limitant la taille de clé.
https://crypto.stackexchange.com/questions/59583/if-and-why-is-it-bad-to-scrypt-a-bcrypted-password/59588#59588
Et si vous n'utilisez que la chaîne de hachage combinée?
@SolomonUcko Ensuite, il devient très vulnérable aux attaques de préimage partielles.
Adam Caudill
2013-04-01 07:03:56 UTC
view on stackexchange narkive permalink

Les primitives cryptographiques peuvent être empilées en toute sécurité et augmenter la sécurité si, et seulement si, vous connaissez suffisamment bien les primitives pour comprendre leurs faiblesses et comment ces faiblesses interagissent. Si vous ne les connaissez pas ou si vous ne comprenez pas les détails, c'est ainsi que vous obtenez le protocole de Dave.

Le problème est que très peu de gens les connaissent tous assez bien pour juger si une certaine combinaison est sûre. C'est pourquoi il faut que ce soit quelque chose qui soit publié et révisé, s'il n'a pas été révisé, vous n'avez aucun moyen de savoir s'il est aussi fort que scrypt ou s'il est plus proche de CRC32.

Donc, si vous n'êtes pas un expert - il est fort possible que vous ayez quelque chose de plus faible que la primitive la plus faible que vous avez utilisée (voir le protocole de Dave) et vous ne le sauriez pas. Ou du moins vous ne le sauriez pas tant qu'il n'est pas fissuré - trouver les mots de passe de vos utilisateurs sur Pastebin n'est pas tout à fait le moyen idéal de déterminer que le schéma est défectueux.

Je suis d'accord qu'un certain degré d'obscurité peut aide d'un point de vue de la défense en profondeur, mais le système sous-jacent doit être sécurisé.

Entre scrypt , bcrypt et PBDKF2 - au moins l'un d'entre eux sera pris en charge sur à peu près toutes les plates-formes. Ceux-ci sont connus et bien testés - ils offrent différents niveaux de protection, mais ils sont toujours beaucoup plus sûrs qu'un empilement bizarre de md5 et sha1 .

Je pense que l'empilement de md5 et sha1 était un mauvais exemple, je n'utiliserais jamais celui-là et c'était juste à titre d'illustration. Je suis particulièrement intéressé par la pile bcrypt-scrypt. Je ne comprends toujours pas comment cela pourrait affaiblir le hachage? Comme je l'ai dit, c'est une étape qui pourrait être franchie par un hacker s'il le voulait de toute façon, donc si cela affaiblit le hachage, c'est un énorme problème même si je ne le fais pas pour eux!
@GeorgePowell: Un hacker n'est pas seulement intéressé par la récupération des mots de passe originaux en texte brut. Il pourrait également être intéressé à trouver des collisions. Il est possible que vous augmentiez le nombre de collisions en enchaînant ces fonctions ensemble.
Pouvez-vous expliquer pourquoi, si un pirate informatique a accès à la base de données, il tente de trouver des collisions? Aussi, sûrement le nombre de collisions créées par une fonction de hachage est-il fonction de sa qualité? Si le hachage d'un hachage entraîne plus de collisions, je suggérerais que la fonction de hachage est médiocre dès le départ.
Thomas Pornin
2013-04-01 22:58:30 UTC
view on stackexchange narkive permalink

Pour votre question spécifique de combiner scrypt et bcrypt, rappelez-vous que ces fonctions ont un coût configurable et que vous voulez augmenter ce coût autant que possible, tout en le maintenant tolérable pour votre utilisation spécifique. Par exemple, si vous pouvez utiliser bcrypt avec jusqu'à X itérations (au-delà de quoi il est trop cher pour votre serveur et votre nombre moyen de connexions utilisateur par seconde), ou scrypt avec jusqu'à Y itérations, alors vous ne pouvez pas utiliser scrypt (bcrypt) avec des itérations X pour bcrypt puis Y itérations pour scrypt: ce sera au-delà votre budget CPU.

Ainsi, si vous cascade scrypt et bcrypt, vous devez utiliser les deux avec moins d'itérations que ce que vous auriez pu faire avec un seul. Vous n'obtenez pas le meilleur des deux mondes en les enchaînant simplement. En fait, le mieux que vous puissiez espérer est une sorte de moyenne entre les deux. Et cela se fait au prix d'un code plus complexe, ce qui est intrinsèquement mauvais quand on parle de sécurité (ou, d'ailleurs, de maintenabilité).

La plupart des algorithmes deviendront probablement plus rapides avec le temps, mais pas nécessairement à parts égales. Supposons qu'il y ait 1% de chances que la méthode X soit accélérée de 100 fois, et 10% de chances qu'elle soit multipliée par deux; de même pour la méthode Y. Sauf si je manque quelque chose, je pense que l'exécution des deux algorithmes à mi-puissance signifierait qu'une accélération massive ne serait possible pour le composite que si l'un était possible pour les * deux * algorithmes constituants.
Oui, les économies d'échelle constituent un autre problème.Mentionné ici: https://security.stackexchange.com/questions/33531/why-improvising-your-own-hash-function-out-of-existing-hash-functions-is-so-bad?rq=1#comment254238_33550
Stephen Touset
2013-04-01 08:10:49 UTC
view on stackexchange narkive permalink

En plus de la réponse d'Adam, j'aimerais également mentionner que chaque fois que vous utilisez la cryptographie, vous devriez avoir une raison forte et inévitable de le faire. Dans vos exemples ci-dessus, cela n'existe pas.

  md5 (md5 (sel) + bcrypt (mot de passe)) scrypt (bcrypt (mot de passe + sel))  

Les algorithmes bcrypt et scrypt sont déjà suffisamment puissants et considérés comme effectivement incassables. Quel problème essayez-vous de résoudre? Et pourquoi pensez-vous que combiner leurs résultats (en particulier avec md5 ) le résoudra? Dans le meilleur des cas, vous avez probablement simplement réduit la difficulté de déchiffrer le mot de passe à celle du hachage le plus faible, plutôt que d'améliorer réellement la sécurité. Et le pire des cas est terriblement indéfini.

  md5 (sha1 (md5 (md5 (mot de passe) + sha1 (mot de passe + sel)) + mot de passe))  

Cette solution est encore pire. Il implémente manuellement un schéma de hachage répété, mais sans suffisamment de tours pour réellement imposer un facteur de travail significatif aux attaquants.

En un mot, le problème est que:

  • vous ' re jeter autour de la cryptographie sans réellement avoir un problème à résoudre
  • vous avez considérablement augmenté la probabilité d'introduire des failles dans votre implémentation
  • vous avez probablement réduit la sécurité au plus faible des algorithmes de hachage, et
  • vous avez introduit un scénario du pire des cas inconnu où aucun n’existait auparavant
Le «problème que j'essaie de résoudre» ou les avantages de les résoudre ont été abordés à la fin de la question. Et je ne comprends toujours pas comment une pile de hachages comme sha1 (md5 (bcrypt ())) pourrait être plus faible que bcrypt! Veuillez expliquer, si mettre md5 au-dessus de bcrypt l'a rendu plus faible, alors pourquoi diable les pirates ne le font-ils pas eux-mêmes une fois qu'ils ont obtenu les mots de passe bcryt-ed?
@GeorgePowell Votre schéma `sha1 (md5 (bcrypt ()))` * n'a aucun sens *. Qu'est-ce qu'il offre que bcrypt seul n'offre pas? Si vous recherchez plus de sécurité dans bcrypt, pourquoi ne pas simplement augmenter le facteur de travail ou passer à scrypt? Abuser d'autres primitives de hachage, en particulier celles principalement cassées comme MD5, pour un avantage indéfini et minuscule (qui peut * en fait * être un détriment) n'est pas intelligent et ne peut que vous fournir plus de complexité.
Je suis d'accord que cela n'a aucun sens, vous avez raison. Cela ne fait pas un meilleur hachage. Mais je ne comprends pas comment cela le rendrait plus faible? Même si vous avez complètement battu les hachages md5 et sha1, vous vous retrouveriez toujours avec toutes les forces de bcrypt? Ou ai-je complètement tort ici?
Le problème de sécurité n'est pas vraiment un problème cryptographique. Vous devez écrire des lignes de code pour produire cette implémentation, et chaque ligne que vous écrivez apporte des vulnérabilités potentielles. Même des choses subtiles comme la façon dont Unicode est géré sur certaines machines peuvent être catastrophiques du point de vue de la sécurité. Restez simple, gardez la mise en œuvre propre de crud inutile, et vous serez plus en sécurité.
@GeorgePowell Cela ne les aide pas. Imaginez qu'il existe une fonction de hachage qui a un espace de sortie d'un seul octet. Il est évidemment * trivial * pour un attaquant de forcer brutalement nos mots de passe si nous l'utilisons à tout moment pour calculer des résumés (même si nous le transmettons plus tard à quelque chose comme `bcrypt`). Mais le fait que ce hachage faible existe ne permet pas à un attaquant de l'utiliser contre nous, car * nous * ne l'utilisons pas.
@GeorgePowell De plus, le "problème" que vous essayez de résoudre n'existe pas réellement. C'est purement imaginaire. Si cela existait, les cryptographes professionnels se démèneraient comme des fous pour proposer une solution permanente. Votre croyance apparente que 1) un problème pratique existe, 2) il n'y a pas de solution publiée, et 3) la «solution» est triviale vient avec l'affirmation implicite que les cryptographes professionnels sont stupides et / ou paresseux. Sinon, ils auraient déjà trouvé une solution, non?
Marcks Thomas
2013-04-01 15:54:51 UTC
view on stackexchange narkive permalink

Si vous appliquez des opérations non sécurisées à un algorithme sécurisé, vous pouvez définitivement interrompre la fonction de hachage. Votre nouvelle fonction pourrait même être bien pire que le lien le plus faible.

Pourquoi les attaquants ne l'utilisent-ils pas pour briser les fonctions sécurisées? Cela ne les aide pas. Par exemple, si j'écrase les 440 premiers bits d'un mot de passe stocké en toute sécurité à l'aide de bcrypt avec des zéros, je peux facilement trouver un mot de passe correspondant par force brute, mais ce mot de passe ne fonctionnera que sur mon propre algorithme terrible. Une implémentation sensée la rejetterait probablement.

La remise à zéro de gros morceaux d'un hachage est clairement mauvaise, mais même des opérations sûres peuvent être combinées en quelque chose de dangereux. Ajouter deux nombres (modulo n pour garantir une longueur constante) est «sûr». En général, aucune entropie n'est perdue. Néanmoins, h (x) + h (x) mod n réduit la qualité du hachage h (x) d’un bit, car le résultat est toujours pair. L'opérateur tout aussi sûr XOR fait encore pire, car h (x) XOR h (x) renvoie toujours zéro.

Ces pièges sont assez évidents, mais ils ne le sont pas tous. Gardez à l'esprit que, comme toujours, il est trivial d'inventer un schéma suffisamment bon pour que vous ne trouviez pas vous-même de faiblesses, mais très difficile d'en inventer un là où personne d'autre ne le peut.

Bonne réponse, je pense que je comprends l'essentiel: des hachages farfelus * pourraient * faciliter la recherche d'une correspondance par force brute, mais ne pourraient pas faciliter la recherche du mot de passe d'origine qui a été utilisé. C'est pourquoi les pirates informatiques n'ont aucune utilité à appliquer eux-mêmes le hachage le plus faible. Cracker le hachage empilé n'implique pas de craquer les hachages internes.
ponsfonze
2013-04-01 12:36:53 UTC
view on stackexchange narkive permalink

Les fonctions de hachage sont construites par des cryptographes et détruites par des cryptographes. Il existe de nombreuses fonctions de hachage fortes ainsi que des fonctions faibles encore utilisées aujourd'hui. Les programmeurs doivent faire confiance aux cryptographes et à la fonction de hachage. S'il y avait jamais une vulnérabilité dans la fonction de hachage, vous en entendrez sûrement parler sur Internet ou par l'intermédiaire de collègues, puis les cryptographes mèneront sûrement une enquête approfondie. Avec tout algorithme de hachage sécurisé, la seule faiblesse connue peut être une attaque bruteforce.

La combinaison de fonctions de hachage n'ajoute presque aucune sécurité supplémentaire et tout ce que vous voudrez peut-être ajouter est probablement déjà implémenté dans la fonction.

Le salage d'un mot de passe est idéal pour réduire l'efficacité contre les tables arc-en-ciel de sorte qu'un mot de passe ne puisse pas être simplement "recherché". Que vous hachiez une fonction deux fois ou que vous changiez la fonction de hachage, il s'agit essentiellement de saler le mot de passe. Et la plupart des fonctions incluent une méthode simple pour saler, il n'est donc vraiment pas nécessaire de l'implémenter.

Disons que je veux créer mon propre hachage sécurisé parce que tout le monde le fait. Et comme je ne suis pas un cryptographe, j'en aurai besoin "vraiment" sécurisé, car bien sûr, chaque programmeur sait faire un hachage sécurisé au lieu d'utiliser les sécurisés déjà créés. Je crée donc ma fonction de hachage sournoise, mod10 (md5 (sha1 (bcrypt (mot de passe + sel)))).

Comme vous pouvez le voir dans ma fonction de hachage, elle est vraiment sécurisée car j'utilise tellement de différents des choses dedans. Bien sûr, dans cet exemple stupide, il est facile de voir qu'il n'y aura que 10 sorties différentes possibles. Mais en utilisant simplement une seule fonction de hachage sécurisée, cela aurait complètement évité cela.

Bien sûr, votre système devrait être sécurisé si l'attaquant a le code source, mais il est très probable que votre l'attaquant n'aura pas accès à votre code source et ne pourra probablement pas deviner votre hachage farfelu, rendant toute tentative de force brute impossible

Nous supposons donc qu'un attaquant s'est emparé de la table de base de données qui contient les hachages. Je suppose qu'il est très probable qu'un attaquant puisse également obtenir les fichiers de la page Web. Vos systèmes exécutant ces services sont peut-être le même exploit qui a permis à votre base de données d'être prise. Un serveur de base de données est configuré pour que le public ne puisse pas y accéder directement. En revanche, votre serveur web contenant votre code, est en première ligne.

Eric G
2013-04-01 09:04:30 UTC
view on stackexchange narkive permalink

Chaque fois que vous augmentez la complexité d'un algorithme ou même ajoutez plus de lignes de code, vous augmentez les points de défaillance de votre application. La combinaison d'algorithmes peut avoir des conséquences inattendues. Cela peut conduire à certains tell ou autres signes qui peuvent en fait affaiblir la force cryptographique du système.

Plus vous utilisez de bibliothèques dans votre application, plus le risque pour votre application en général est grand. Si une faille est trouvée dans une implémentation qui permet une faiblesse, l'exécution de code, etc. alors votre application est vulnérable. Si par hasard vous avez choisi un autre algorithme qui n'a pas été attaqué, votre coffre-fort pour le moment (bien sûr, vous pourriez aussi être du côté malchanceux de la chance).

N'oubliez pas KISS : restez simple, stupide, sinon vous risquez de vous perdre dans la complexité.

emory
2013-04-02 05:05:12 UTC
view on stackexchange narkive permalink

Je ne suis pas d'accord avec tout un tas de gens qui sont plus intelligents que moi et plus expérimentés en sécurité que moi. Donc je me trompe probablement.

Improviser votre propre fonction de hachage est une bonne idée - si vous le faites correctement. Suivez ces 3 étapes simples.

  1. Identifiez une faiblesse ou une faille dans les fonctions de hachage existantes.
  2. Improvisez votre propre fonction de hachage qui n'a pas cette faille.
  3. Vérifiez que votre fonction de hachage improvisée possède toutes les forces des fonctions de hachage existantes.

Après avoir terminé l'étape 3, vous seriez un idiot de ne pas utiliser votre fonction de hachage improvisée.

  • / p>
  • Le problème est que vous * ne pouvez pas * terminer l'étape 3. Personne au monde n'est capable de déterminer unilatéralement qu'un nouvel algorithme de hachage est puissant. C'est pourquoi, pour être acceptés, les nouveaux algorithmes candidats passent par des compétitions massives pluriannuelles évaluées par des pairs et font l'objet d'un examen minutieux exceptionnel. Vous ne pouvez tout simplement pas savoir si un algorithme est en sécurité dans le vide.
    @Xander, Je ne peux terminer aucune des étapes. Donc pour moi, je n'improvise pas. Alors que l'étape 3 est probablement la plus importante, l'étape 1 est la plus élémentaire. Si vous ne pouvez pas au moins identifier un problème avec une fonction de hachage sécurisée existante, alors pourquoi perdez-vous votre temps à improviser une nouvelle fonction de hachage.
    user3083447
    2016-12-13 20:55:07 UTC
    view on stackexchange narkive permalink

    Lors de la concaténation de différentes fonctions de hachage parce que vous vous inquiétez de celle, il est vital que vous appliquiez le sel avant d'appliquer le prochain algorithme de hachage, alors toute faiblesse de collision dans l'un des algorithmes ne corrompra pas la deuxième fonction de hachage que vous en utilisant:

    scrypt (bcrypt (mot de passe + sel) + sel)

    Mais je pense que scrypt est une technique établie maintenant, Argon 2i a remporté le concours de hachage de mot de passe et est censé être plus sécurisé et bcrypt existe depuis longtemps et s'est avéré sécurisé contre les contournements triviaux.

    Par conséquent, ce qui suit aurait plus de sens, et combinerait la force de l'argon 2i, mais reviendrait à bcrypt si un futur attaquant montrait comment casser trivialement argon 2i, ce qui est actuellement considéré comme difficile:

    bcrypt (Argon2i (mot de passe + sel) + sel)

    Mais vous êtes moins probable faire une erreur si vous faites simplement:

    scrypt (mot de passe + sel) Orbcrypt (mot de passe + sel)

    Rappelez-vous, la plupart des violations sont dues à une erreur humaine r dans le code, il est préférable de rester simple et de revoir en profondeur votre code avec une analyse dynamique et statique et des réviseurs de code humains, pour vous assurer qu'aucune attaque par injection SQL ne passe (n'oubliez pas de toujours paramétrer vos requêtes de base de données!)

    lepe
    2016-04-13 07:06:44 UTC
    view on stackexchange narkive permalink

    J'ai beaucoup appris avec ce fil, j'ai donc pensé de manière à comprendre facilement le résultat possible en combinant différentes méthodes (bien sûr, cela ne conviendra pas à tous les cas):

    [W = faible, S = fort]:

      Formule | Exemple --------------- | ----------------- W (W) = W | md5 (sha1 (pwd)) W (S) = W | md5 (bcrypt (pwd)) S (W) = W | bcrypt (md5 (pwd)) S (S) = S- | bcrypt (scrypt (pwd)) // leur interaction est inconnue W + S = W | md5 (pwd) + brcypt (pwd) S + S = W | bcrypt (pwd) + scrypt (pwd) W '+ S "= S | md5 (pwd1) + brcypt (pwd2) // pwd1! = pwd2S' + S" = 2S | bcrypt (pwd1) + scrypt (pwd2) // pwd1! = pwd2SUBSTR (W) = W | substr (md5 (pwd), n); // Plus court la chaîne, le plus faibleSUBSTR (S) = S- | substr (bcrypt (pwd), n); // Plus la chaîne est courte, plus la chaîne est faible S + x = S + | bcrypt (pwd) + x // x = Variable str. sans rapport avec pwdS (S + x) = S- | bcrypt (scrypt (pwd) + x) // x = Variable str. sans rapport avec pwdROT13 (S) = S | ROT13 (bcrypt (pwd)) 

    Ce que je veux réaliser ici est de montrer d'une manière simple que ces combinaisons n'ajouteront pas de sécurité supplémentaire dans la plupart des cas (donc la complexité supplémentaire est pas digne).

    Il est impossible de dire une chose aussi générale que «S (S) = S-».Comme Polynomial l'a expliqué dans un commentaire ci-dessus, la répétition d'une fonction de hachage forte peut en principe entraîner un hachage complètement inutile.Sur quoi reposent ces «formules»?
    @GeorgePowell: Oui, `S (S)` pourrait conduire à un comportement inattendu, ce qui pourrait potentiellement entraîner un hachage inutile.C'est pourquoi il est marqué: «S-», ce qui signifie qu'il sera moins fort que «S» seul, donc ce n'est pas recommandé.Comme nous ne spécifions pas les algorithmes réels, nous ne pouvons pas être sûrs à 100% que cela produira des hachages inutiles, mais devrait être évité en raison d'un tel risque.Ces «formules» n'ont aucun fondement scientifique et ne sont que ma tentative de représenter de telles interactions d'une manière simple afin que quiconque essaie de «gérer sa propre» puisse avoir une idée de ce à quoi s'attendre et éviter leur utilisation.
    @lepe, `W (S) = W`?Êtes-vous sûr?Voir https://security.stackexchange.com/questions/33531/why-improvising-your-own-hash-function-out-of-existing-hash-functions-is-so-bad?rq=1#comment52264_33550
    @Pacerier: Un point à analyser est la "probabilité de collision".Si vous utilisez MD5 pour hacher un hachage bcrypt, vous augmentez les chances de collision et par conséquent, vous réduisez sa force.De plus, si le hachage MD5 est compromis, forcer le hachage MD5 directement pourrait être beaucoup plus rapide, en supprimant «S» de la formule (en fonction de l'implémentation, cela pourrait être un énorme problème).Un autre point est que si l'algorithme W a une faille de sécurité, il peut également rendre le W (S) défectueux.Pour ces raisons, W (S) ne doit jamais être considéré comme S ou S +.Il est préférable d'utiliser S seul pour éviter d'ajouter de la complexité et des risques inutiles.
    @lepe, ** 1) ** Bien sûr, vous pouvez brutaliser `W`, mais brutforcer` W` vous donne `S (mot de passe)`, pas le mot de passe lui-même.En d'autres termes, après avoir brutalisé «W», vous êtes ** de retour à la case départ **.Voir le lien vers le commentaire de Root ci-dessus.** 2) ** Ensuite, si l'algorithme `W` a une faille de sécurité, il ** ne peut pas ** rendre` W (S) `défectueux.[cont]
    [cont] Parce que si «W (S)» est défectueux, alors «S» ne s'appellerait plus «S» puisque «S» serait alors considéré comme cassé et non plus comme un hachage ** S ** trong.http://en.wikipedia.org/wiki/Self-refuting_idea.En d'autres termes, avant que nous soyons piratés, quelqu'un aurait fait l'actualité mondiale en cassant «S».Bien qu'il soit certainement vrai qu'il y a une chance que le monde ait des crackers avec plus d'expertise que les chercheurs et cryptanalystes blancs, permettant à la connaissance d'avoir cassé `S` de circuler sur le marché noir pendant plus longtemps avant qu'il ne soit publiquement connu.
    Bonne table sauf ROT13 (S) = S.Je conseille à certaines personnes qui craignent vraiment la carte ASIC stock de faire XOR (S, key) où la clé est stockée ailleurs donc ...
    @Pacerior: J'ai vu quelques cas où W était si mauvais qu'il était possible de bruer W (S).Indice: si W a une entropie de 64 bits, 1 << 63 essais suffiront en moyenne.
    @Pacerier: J'ai changé ROT13 (S) = S comme suggéré.


    Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
    Loading...