Are there any SHA-256 javascript implementations that are generally considered trustworthy?
OUTDATED: Many modern browsers now have first-class support for crypto operations. See Vitaly Zdanevich's answer below.
The Stanford JS Crypto Library contains an implementation of SHA-256. While crypto in JS isn't really as well-vetted an endeavor as other implementation platforms, this one is at least partially developed by, and to a certain extent sponsored by, Dan Boneh, who is a well-established and trusted name in cryptography, and means that the project has some oversight by someone who actually knows what he's doing. The project is also supported by the NSF.
It's worth pointing out, however...
... that if you hash the password client-side before submitting it, then the hash is the password, and the original password becomes irrelevant. An attacker needs only to intercept the hash in order to impersonate the user, and if that hash is stored unmodified on the server, then the server is storing the true password (the hash) in plain-text.
So your security is now worse because you decided add your own improvements to what was previously a trusted scheme.
On https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest I found this snippet that uses internal js module:
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;}
Note that crypto.subtle
in only available on https
or localhost
- for example for your local development with python3 -m http.server
you need to add this line to your /etc/hosts
:0.0.0.0 localhost
Reboot - and you can open localhost:8000
with working crypto.subtle
.
For those interested, this is code for creating SHA-256 hash using sjcl
:
import sjcl from 'sjcl'const myString = 'Hello'const myBitArray = sjcl.hash.sha256.hash(myString)const myHash = sjcl.codec.hex.fromBits(myBitArray)