Y a-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 changer le mot de passe côté client en javascript avant de l'envoyer sur le serveur. J'ai du mal à trouver quelle implémentation SHA-256 je peux faire confiance. Je m'attendais à ce qu'il y ait une sorte de script faisant autorité que tout le monde utilise, mais je trouve des tas de projets différents tous avec leurs propres implémentations.

je me rends compte que l'utilisation de la crypto des autres 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 "digne de confiance", mais cela semble être quelque chose de commun et assez important qu'il devrait y avoir une sorte de consensus sur ce qu'il faut utiliser. Suis-je naïf?

édite depuis qu'il apparaît beaucoup dans les commentaires: Oui, nous faisons à nouveau un hachage plus strict du côté du serveur. Le hachage côté client n'est pas le résultat final que nous enregistrons dans la base de données. Le hashing côté client est parce que le client humain les demandes. Ils n'ont pas donné de raison spécifique pour laquelle, probablement ils aiment juste exagérer.

51
demandé sur jono 2013-08-19 21:15:47

7 réponses

Le Stanford JS Bibliothèque Crypto contient une implémentation de l'algorithme SHA-256. Alors que crypto in JS n'est pas vraiment un effort aussi bien approuvé que d'autres plates-formes de mise en œuvre, celui-ci est au moins partiellement développé par, et dans une certaine mesure parrainé par, Dan Boneh , qui est un nom bien établi et de confiance dans la cryptographie, et signifie que le projet a une certaine surveillance par quelqu'un qui sait réellement ce qu'il fait. Le projet est également pris en charge par le NSF .

il est intéressant de noter, cependant...

... que si vous hachez le mot de passe côté client avant de le soumettre , alors le hachage est le mot de passe , et le mot de passe original devient hors de propos. 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 le serveur stocke le true mot de passe (le hachage) 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 régime de confiance.

62
répondu tylerl 2017-03-17 13:14:46

Forge 's SHA-256 l'implémentation est rapide et fiable.

pour exécuter des tests sur plusieurs implémentations JavaScript SHA-256, allez à 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 beaucoup plus rapide que la bibliothèque de cryptage JavaScript de Stanford (sjcl) mentionnée dans la réponse acceptée.

Forge est de 256 KB, mais l'extraction du code SHA-256 réduit la taille à 4.5 KB, voir https://github.com/brillout/forge-sha256

11
répondu brillout 2015-07-22 19:13:12

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

Quel est le problème "poule mouillée" avec la livraison de la cryptographie Javascript?

si vous ne faites pas confiance au réseau pour fournir un mot de passe, ou, pire, ne faites pas confiance au serveur pour ne pas garder les secrets d'utilisateur, vous ne pouvez pas faire confiance pour la livraison de code de sécurité. Le même attaquant qui reniflait des mots de passe ou des journaux intimes avant de vous introduire crypto est tout simplement détourner le code crypto après que vous le faites.

[...]

pourquoi ne puis-je pas utiliser TLS/SSL pour transmettre le code de cryptage Javascript?

vous pouvez. C'est plus difficile qu'il n'y paraît, mais vous transmettez en toute sécurité la cryptographie Javascript à un navigateur en utilisant SSL. Le problème est que, après avoir établi un voie de communication protégée avec SSL, vous n'avez plus besoin de la cryptographie Javascript; vous avez une cryptographie "réelle".

qui mène à ceci:

le problème avec L'exécution de code de crypto en Javascript est que pratiquement n'importe quelle fonction dont la crypto dépend pourrait être dépassée silencieusement par n'importe quel morceau de contenu utilisé pour construire la page d'hébergement. La sécurité cryptographique pourrait être désactivée au début du processus (en générant de faux nombres aléatoires, ou par altérer les constantes et les paramètres utilisés par les algorithmes), ou plus tard (en ramenant le matériel clé à un attaquant), ou - - dans le scénario le plus probable - - - en contournant entièrement la crypto.

il n'y a aucun moyen fiable pour un morceau de code Javascript de vérifier son environnement d'exécution. Le code de chiffrement Javascript ne peut pas demander :" ai-je vraiment affaire à un générateur de nombres aléatoires, ou à un fac-similé d'un générateur fourni par un attaquant?" et il ne peut certainement pas affirmer que"personne n'est autorisé à faire quoi que ce soit avec ce secret de crypto, sauf de façons que moi, l'auteur, approuve". ce sont deux propriétés qui sont souvent fournies dans d'autres environnements qui utilisent la cryptographie, et ils sont impossibles en Javascript.

fondamentalement, le problème est celui-ci:

  • 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 fourni par vos serveurs (ceux auxquels ils ne font pas confiance).

ou alternativement,

  • Vos clients ne font pas confiance à SSL, ils veulent donc que vous utilisiez un code de sécurité supplémentaire.
  • ce code de sécurité est livré via SSL.

Note: aussi, SHA-256 n'est pas adapté pour cela, car il est si facile de force brute mots de passe non itérés . Si vous décidez de le faire de toute façon, cherchez une implémentation de bcrypt , scrypt ou PBKDF2 .

8
répondu Brendan Long 2013-10-04 16:29:28

j'ai trouvé cette implémentation très facile à utiliser. A également une licence de style BSD généreuse:

jsSHA: https://github.com/Caligatio/jsSHA

j'avais besoin d'un moyen rapide pour obtenir la représentation hexagonale D'un hachage SHA-256. Il n'a pris que 3 lignes:

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");
7
répondu cobbzilla 2016-06-02 00:28:05

sur https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest j'ai trouvé cet extrait qui utilise le module interne js:

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder('utf-8').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 => ('00' + b.toString(16)).slice(-2)).join('');
    return hashHex;
}
6
répondu Vitaly Zdanevich 2018-01-09 05:05:15

pour les personnes intéressées, c'est le code pour créer du hash 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)
3
répondu Danny Sullivan 2018-02-12 01:37:39

en plus de la lib de Stanford que tylerl a mentionné. J'ai trouvé jsrsasign très utile (GitHub repo ici: https://github.com/kjur/jsrsasign ). Je ne sais pas à quel point il est fiable, mais j'ai utilisé son API de SHA256, Base64, RSA, x509, etc. et ça marche plutôt bien. En fait, il inclut également le Stanford lib.

si tout ce que vous voulez faire est SHA256, jsrsasign pourrait être une overkill. Mais si vous ont d'autres besoins dans le domaine, je pense que c'est un bon ajustement.

1
répondu Faraway 2015-12-11 22:29:03