179 votes

Existe-t-il des implémentations javascript SHA-256 qui sont généralement considérées comme fiables ?

J'écris un login pour un forum, et j'ai besoin de hacher le mot de passe côté client en javascript avant de l'envoyer au serveur. J'ai du mal à trouver l'implémentation SHA-256 à laquelle je peux faire confiance. Je m'attendais à ce qu'il y ait une sorte de script faisant autorité et que tout le monde utilise, mais je trouve des tas de projets différents, tous avec leurs propres implémentations.

Je sais que l'utilisation de la cryptographie d'autres personnes est toujours un acte de foi, à moins que vous ne soyez qualifié pour l'examiner vous-même, et qu'il n'y a pas de définition universelle de "fiable", mais cela semble être quelque chose de commun et d'assez important pour qu'il y ait une sorte de consensus sur ce qu'il faut utiliser. Suis-je simplement naïf ?

Editer puisque cela revient souvent dans les commentaires : Oui, nous effectuons à nouveau un hachage plus rigoureux du côté serveur. Le hachage côté client n'est pas le résultat final que nous sauvegardons dans la base de données. Le hachage côté client est effectué parce que le client humain le demande. Ils n'ont pas donné de raison spécifique, probablement qu'ils aiment juste l'exagération.

203voto

Vitaly Zdanevich Points 2264

Sur https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest J'ai trouvé ce snippet qui utilise le module js interne :

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder().encode(message);                    

    // hash the message
    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);

    // convert ArrayBuffer to Array
    const hashArray = Array.from(new Uint8Array(hashBuffer));

    // convert bytes to hex string                  
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
}

Notez que crypto.subtle disponible uniquement sur https ou localhost - par exemple pour votre développement local avec python3 -m http.server vous devez ajouter cette ligne à votre /etc/hosts : 0.0.0.0 localhost

Redémarrez - et vous pourrez ouvrir localhost:8000 avec le travail crypto.subtle .

143voto

tylerl Points 14541

EN FIN DE VIE : De nombreux navigateurs modernes disposent désormais d'un support de premier ordre pour les opérations cryptographiques. Voir La réponse de Vitaly Zdanevich ci-dessous.


El Bibliothèque cryptographique de Stanford JS contient une implémentation de SHA-256. Bien que la cryptographie en JS ne soit pas vraiment une entreprise aussi bien contrôlée que d'autres plates-formes d'implémentation, celle-ci est au moins partiellement développée et, dans une certaine mesure, sponsorisée par.., Dan Boneh Il s'agit d'un nom bien établi et digne de confiance dans le domaine de la cryptographie, ce qui signifie que le projet est supervisé par quelqu'un qui sait réellement ce qu'il fait. Le projet est également soutenu par le NSF .

Il est utile de souligner, cependant...
... que si vous hachiez le mot de passe côté client avant de le soumettre, alors l hash est le mot de passe et le mot de passe original n'est plus pertinent. Un attaquant n'a besoin que d'intercepter le hachage pour se faire passer pour l'utilisateur, et si ce hachage est stocké sans modification sur le serveur, alors le serveur stocke le vrai mot de passe (le hash) en clair .

Donc votre sécurité est maintenant pire parce que vous avez décidé ajouter vos propres améliorations à ce qui était auparavant un système de confiance.

41voto

Danny Sullivan Points 1203

Pour ceux qui sont intéressés, voici le code pour créer un hachage SHA-256 en utilisant sjcl :

import sjcl from 'sjcl'

const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)

21voto

brillout.com Points 2289

Forge La mise en œuvre de SHA-256 est rapide et fiable.

Pour effectuer des tests sur plusieurs implémentations JavaScript de SHA-256, rendez-vous à l'adresse suivante http://brillout.github.io/test-javascript-hash-implementations/ .

Les résultats sur ma machine suggèrent que forge est l'implémentation la plus rapide et aussi considérablement plus rapide que la Stanford Javascript Crypto Library (sjcl) mentionnée dans la réponse acceptée.

La taille de Forge est de 256 Ko, mais l'extraction du code lié à SHA-256 réduit la taille à 4,5 Ko, cf. https://github.com/brillout/forge-sha256

15voto

Brendan Long Points 24372

Non, il n'y a aucun moyen d'utiliser le JavaScript du navigateur pour améliorer la sécurité des mots de passe. Je vous recommande vivement de lire cet article . Dans votre cas, le plus gros problème est celui de l'œuf et de la poule :

Quel est le "problème de l'œuf et de la poule" avec la cryptographie Javascript ?

Si vous ne faites pas confiance au réseau pour délivrer un mot de passe ou, pire, si vous ne faites pas confiance au serveur pour ne pas garder les secrets des utilisateurs, vous ne pouvez pas lui faire confiance pour délivrer un code de sécurité. Le même attaquant qui reniflait les mots de passe ou lisait les journaux intimes avant que vous n'introduisiez la cryptographie ne fait que détourner le code cryptographique après que vous l'ayez fait.

[...]

Pourquoi ne puis-je pas utiliser TLS/SSL pour transmettre le code cryptographique Javascript ?

Tu peux. C'est plus difficile qu'il n'y paraît, mais vous pouvez transmettre en toute sécurité le cryptage Javascript à un navigateur en utilisant SSL. Le problème est qu'après avoir établi un canal sécurisé avec SSL, vous n'avez plus besoin de la cryptographie Javascript ; vous avez la "vraie" cryptographie.

Ce qui nous amène à ceci :

Le problème de l'exécution d'un code de cryptage en Javascript est que pratiquement toutes les fonctions dont dépend le cryptage peuvent être remplacées silencieusement par n'importe quel élément de contenu utilisé pour construire la page d'hébergement. La sécurité cryptographique peut être annulée au début du processus (en générant de faux nombres aléatoires ou en modifiant les constantes et les paramètres utilisés par les algorithmes), ou plus tard (en remettant les clés à un attaquant), ou encore dans le scénario le plus probable --- en contournant entièrement la cryptographie.

Il n'existe aucun moyen fiable pour un morceau de code Javascript de vérifier son environnement d'exécution. Le code cryptographique Javascript ne peut pas demander : "Suis-je vraiment en présence d'un générateur de nombres aléatoires ou d'un fac-similé de générateur fourni par un pirate ? Et il ne peut certainement pas affirmer "personne n'est autorisé à faire quoi que ce soit avec ce secret cryptographique, sauf de la manière que moi, l'auteur, j'approuve". Ce sont deux propriétés qui sont souvent fournies dans d'autres environnements qui utilisent la cryptographie, et elles sont impossibles en Javascript.

En gros, le problème est le suivant :

  • Vos clients ne font pas confiance à vos serveurs, ils veulent donc ajouter un code de sécurité supplémentaire.
  • Ce code de sécurité est délivré par vos serveurs (ceux auxquels ils ne font pas confiance).

Ou alternativement,

  • Vos clients n'ont pas confiance en SSL, ils veulent donc que vous utilisiez un code de sécurité supplémentaire.
  • Ce code de sécurité est délivré via SSL.

Note : SHA-256 n'est pas non plus adapté à cette situation, car il est si facile de force brute mots de passe non scellés et non itérés . Si vous décidez quand même de le faire, cherchez une implémentation de bcrypt , scrypt ou PBKDF2 .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X