Are there any SHA-256 javascript implementations that are generally considered trustworthy? [closed]
Asked Answered
S

10

170

I am writing a login for a forum, and need to hash the password client side in javascript before sending it on to the server. I'm having trouble figuring out which SHA-256 implementation I can actually trust. I was expecting there to be some kind of authoritative script that everyone used, but I'm finding loads of different projects all with their own implementations.

I realize using other people's crypto is always a leap of faith unless you're qualified to review it yourself, and that there is no universal definition of "trustworthy", but this seems like something common and important enough that there ought to be some kind of consensus on what to use. Am I just naive?

Edit since it comes up a lot in the comments: Yes, we do a more stringent hash again on the server side. The client side hashing is not the final result that we save in the database. The client side hashing is because the human client requests it. They have not given a specific reason why, probably they just like overkill.

Spanishamerican answered 19/8, 2013 at 17:15 Comment(18)
If a script produces the same hashes as the reference implementation on your server, what else are you looking for?Monck
@Monck If checking for consistent hashes is the only thing you need to validate a hash algorithm then this question is a bit silly, yeah. I just thought there were maybe potentially other things that could go wrong with a poorly written SHA algorithm than just inconsistent results? After everyone telling me to never, ever, ever try to roll my own I just assumed there would be more to itSpanishamerican
Not to get off topic, but why are you hashing the password on the client side?Shagreen
crypto "don't roll your own" applies mostly to inventing your own algorithm. For well known algorithms "why bother" is the main reason. Bad implementations will be weeded out pretty rapidly.Monck
@SteveS The client (the human one) wants it that way. We do use https, but they'd rather the password is never plaintext anywhere except on the user's end. We use better hashing algorithms on the server sideSpanishamerican
@Monck Not even close. "Don't roll your own" applies to inventing your own algorithm, writing your own implementation of an algorithm, developing your own protocol on top of crypto algorithms, or pretty much anything above using as high-level an abstraction as is available. If you think you'll be safe sticking to a secure core, and only writing glue code, you're gonna have a bad time.Allowable
if you use a hashed password without a challenge/response protocol, then the hashed password IS the password and it's really the same as transmitting the password in clear text.Monck
@Monck There is some value in protecting the user's plaintext password for all the other sites they might use it on, if not for our site in particular. It's an easy fix that maybe won't help us but can potentially help the user if we screw up somewhere. And like I said, client request, nothing I can do about it even if I wanted to.Spanishamerican
@Spanishamerican I know it won't change your client's mind, or your mind, but I can tell you that many times during a pen test, I have been able to pivot much more effectively than I might have otherwise by being able to directly use an admin's password hash I obtained from a web server's database to gain admin privileges in the web application and upload a shell for further pivoting. The passwords were actually pretty good and would've taken me a while to crack, but since I could use the hash directly there was essentially no barrier between SQL injection -> local shell.Suzisuzie
@Suzisuzie I'm more than open to having my mind changed :) but in this case, I don't really understand how your point applies. We hash the password twice: once on the client side with a simple SHA-256, and once on the server side with something more demanding. The first to protect the plaintext in case of MITM or similar, and the second for brute protection. Even if you got a hold of the database and the admin hash you couldn't use that directly to validate the login.Spanishamerican
On the topic of client-side password hashing, see Client side password hashing. For the good it does, use rot13 on the client side, and a proper password hashing algorithm (PBKDF2 or bcrypt or scrypt, accept no substitute) on the server.Kemeny
@Spanishamerican Ah, since you're hashing in both places then yeah, my point is moot. I was unaware that you were doing hashing on the server-side as well.Suzisuzie
@Gilles That's exactly what we do. My own personal justification for hashing client side is to protect the user's plaintext (which they might use elsewhere) in case of a MITM. Yes, https does a better job of that but client side hashing is not a hard thing to implement and is just intended as partial damage control in case the https is not set up properly. Is there something wrong with that reasoning that I'm missing? Or do you just disagree that it's worth the effort?Spanishamerican
@Spanishamerican A fast hash doesn't protect the user's password, whether it's obtained from a database dump or from eavesdropping over the wire.Kemeny
@Gilles It does if it's a strong password. I don't hold any illusions that this is a perfect defense against all attackers, but it's an easy defense against some attackers. Damage mitigation on top of best practices, not delusions of a new computationally secure design.Spanishamerican
@Gilles It can only help, at least when used in combination with a slow hash on the server.Suzisuzie
@Suzisuzie It might not help if it gives a false sense of security. If a SHA-2 of your password is leaked, you need to treat it as a leak of your password anyway. A slow hash can only help if it's implemented correctly (and complexity is intrinsically detrimental to security).Kemeny
If you stumbled on this question because you are looking for a fast and compact SHA-256 implementation then see this related question: stackoverflow.com/questions/31219009/…Clareta
F
143

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.

Flaring answered 19/8, 2013 at 22:44 Comment(19)
If you hash again on the server however, this practice is perfectly legitimate.Arezzini
@NickBrunt if you hash on the server then you're not saving the transmitted password, but you haven't added any security beyond transmitting the original password as opposed to transmitting the password hash, since in either case what you're transmitting is the real password.Flaring
True, but it's not worse than sending a password which is possibly used elsewhere on the Internet in plaintext.Arezzini
I agree with @NickBrunt . It is better if the attacker reads a random hash string that may fit only with this particular app rather than the original password that may be used in several places.Pocky
I need to use client-side hashing because i don't want the server to ever see the user's plaintext password. Not for added security to the service I'M providing, but towards the user. I'm not only saving the user's hash salted with a constant salt (constant per user, not globally) but also re-hashing it with a random session salt every login which DOES provide a little extra security over the network against sniffing. If the server gets compromised it's game over, but that's true for anything not truely p2p anyways.Mausoleum
If you hashed it with something specific to the site (like domain name or something) then it would at least protect user's a little bit who reuse passwords on multiple sites.Magnuson
I think its about the level of service you care to provide your users. If you hash passwords pre-transit, the network effect is that you protect the whole community, because the attacker could only steal your doubled-hashed passwords, and not be able to use them to log into another service (assuming you salt). If your user's passwords are sent without hashing client-side and a mitm ssl strip attack circumvents encryption, then the attacker would have a user's password in plain-text. If that user is a hospital admin, you may miss an opportunity to block a serious hipaa breach in another system.Coulter
What about double hashing? :) Once on client-side and than one more time on server. So that server doesn't know raw password and having sniffed client-side hash hacker still won't be able to log in.Southworth
@Flaring hashing real password on the client before sending to server is even more secure, as the real text password never hits the wire, so just perfect for non-https transport. Also, the double-hashing is not necessary ( though recommended i.e. salting ), having a hash value for attacker has no value, because the log-in sequence on the server will/shall always hash a provided value before comparing against datastore.Mold
@Flaring Your answer comes up as first result in some searches for client-sided hashing. Since the commenters have already desputed your confusing claim about how hashing on the client side is supposedly worse, i think it would be cool if you would edit your answer.Hoxie
@DigitalNinja The answer is still correct -- the claim as stated is that hashing client-side instead of server-side is worse. It most definitely is worse, and nobody disputes this fact. The counter-claim in the comments is that hashing both client-side and server-side is better. It might (sometimes) be no worse than hashing only server side. But it's not better, it's just different in a way that's unhelpful. (next comment for why double-hashing can be worse, not just harmless)Flaring
@DigitalNinja What makes this flavor of double-hashing worse is that nobody sensible does it, so if you try to use it then you'll have to forge your own path for how to integrate this technique, and there's a really good chance you'll screw things up in the process. For example, imagine someone trying to extend this system to include salted hashes -- you've better than even odds that doing so would be an utter disaster. But what's more, the whole thing is cargo-cult cryptography to begin with. You're sprinkling hashes onto your process like they're magic talismans. More doesn't mean better.Flaring
@Flaring Fair enough, but your post says "your security is now worse". Wouldn't it, in the worst-case scenario, just stay the same?Hoxie
@Flaring Oh, one more thing (because i'm in this situation right now), if you hash it client-side as well, you avoid (accidentally or otherwise) logging user's literal passwords in your log files (be it the app logs, or server logs).Hoxie
@DigitalNinja Whatever shared-secret token gets transmitted to the server (not what gets typed into the web page) is the "literal password" for all relevant purposes, including breach disclosure, log files, and other failures. Naively it might seem it improves your "literal passwords" , but situational limitations prevent it from actually helping. Possible downside is you'll act as if this step adds value, and could compromise "real" security when evaluating trade-offs. There is no possible upside as described. Under no scenario is your situation better than without client-side hashing.Flaring
@Flaring It's the literal password for all relevant purposes regarding the site it happens on. But isn't the reason we hash passwords to prevent snoopers from reusing a person's (typed) password in other apps, in case they use the same password on multiple platforms?Hoxie
@DigitalNinja It's been six years since I first asked this question, and I've come to realize that nobody on this page will acknowledge the very specific question of double hashing to protect a user's repeated plaintext password on other sites. Probably because it can't be generalized, so it's not a very interesting question to engage with. To answer your question: Yes, it does help, if 1) the request is MITM'd, 2) the user has reused the password elsewhere, 3) it is a strong password that can't be easily cracked. It's a fairly niche protection, so most don't bother.Spanishamerican
According to GDPR the plain text password is personal data which must not be transmitted before the user has accepted your privacy rules. With a hashed password you are transmitting pseudonymous data, which does not fall under the GDRP privacy rules (as long as you cannot correlate personal data with this password). Also if the hashed password leaks, you do not have a problem with GDPR, as only pseudonymous data leaks. (Same is true for usernames. As usernames must be associated with the password, you need to hash them too to obey to the GDPR, else pseudonymous becomes personal.)Cerallua
Playing around law definitions is not relevant to cryptographic security. Just make a checkbox with a link to EULA as required for the registration form and you are GDPR-compliant now. Leaking client hashes is irrelevant to cryptographic security too. The reason any attacker guesses passwords is not for passwords themselves, but the slew of personal data they unlock. And in this regard ssn used as a password provides no less security than a sha256 hash of it.Halvaard
P
194

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.

Palladio answered 9/1, 2018 at 5:5 Comment(5)
This is awesome. Thank you. Is a comparable API available in Node.js?Krystin
The builtin 'crypto' library should do just fine: nodejs.org/dist/latest-v11.x/docs/api/crypto.htmlStirring
Fails for me (Chrome 88): TypeError: Cannot read property 'digest' of undefined. For unknown reason crypto.subtle is only defined in HTTPS context which makes it unsuitable for general use.Cerallua
@Cerallua may this help? https://mcmap.net/q/25291/-how-can-i-hash-a-string-with-sha256/7389293 Look at the question's update.Armorer
@Cerallua "general use" typically means HTTPS now that we're in the 21st century.Reservoir
F
143

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.

Flaring answered 19/8, 2013 at 22:44 Comment(19)
If you hash again on the server however, this practice is perfectly legitimate.Arezzini
@NickBrunt if you hash on the server then you're not saving the transmitted password, but you haven't added any security beyond transmitting the original password as opposed to transmitting the password hash, since in either case what you're transmitting is the real password.Flaring
True, but it's not worse than sending a password which is possibly used elsewhere on the Internet in plaintext.Arezzini
I agree with @NickBrunt . It is better if the attacker reads a random hash string that may fit only with this particular app rather than the original password that may be used in several places.Pocky
I need to use client-side hashing because i don't want the server to ever see the user's plaintext password. Not for added security to the service I'M providing, but towards the user. I'm not only saving the user's hash salted with a constant salt (constant per user, not globally) but also re-hashing it with a random session salt every login which DOES provide a little extra security over the network against sniffing. If the server gets compromised it's game over, but that's true for anything not truely p2p anyways.Mausoleum
If you hashed it with something specific to the site (like domain name or something) then it would at least protect user's a little bit who reuse passwords on multiple sites.Magnuson
I think its about the level of service you care to provide your users. If you hash passwords pre-transit, the network effect is that you protect the whole community, because the attacker could only steal your doubled-hashed passwords, and not be able to use them to log into another service (assuming you salt). If your user's passwords are sent without hashing client-side and a mitm ssl strip attack circumvents encryption, then the attacker would have a user's password in plain-text. If that user is a hospital admin, you may miss an opportunity to block a serious hipaa breach in another system.Coulter
What about double hashing? :) Once on client-side and than one more time on server. So that server doesn't know raw password and having sniffed client-side hash hacker still won't be able to log in.Southworth
@Flaring hashing real password on the client before sending to server is even more secure, as the real text password never hits the wire, so just perfect for non-https transport. Also, the double-hashing is not necessary ( though recommended i.e. salting ), having a hash value for attacker has no value, because the log-in sequence on the server will/shall always hash a provided value before comparing against datastore.Mold
@Flaring Your answer comes up as first result in some searches for client-sided hashing. Since the commenters have already desputed your confusing claim about how hashing on the client side is supposedly worse, i think it would be cool if you would edit your answer.Hoxie
@DigitalNinja The answer is still correct -- the claim as stated is that hashing client-side instead of server-side is worse. It most definitely is worse, and nobody disputes this fact. The counter-claim in the comments is that hashing both client-side and server-side is better. It might (sometimes) be no worse than hashing only server side. But it's not better, it's just different in a way that's unhelpful. (next comment for why double-hashing can be worse, not just harmless)Flaring
@DigitalNinja What makes this flavor of double-hashing worse is that nobody sensible does it, so if you try to use it then you'll have to forge your own path for how to integrate this technique, and there's a really good chance you'll screw things up in the process. For example, imagine someone trying to extend this system to include salted hashes -- you've better than even odds that doing so would be an utter disaster. But what's more, the whole thing is cargo-cult cryptography to begin with. You're sprinkling hashes onto your process like they're magic talismans. More doesn't mean better.Flaring
@Flaring Fair enough, but your post says "your security is now worse". Wouldn't it, in the worst-case scenario, just stay the same?Hoxie
@Flaring Oh, one more thing (because i'm in this situation right now), if you hash it client-side as well, you avoid (accidentally or otherwise) logging user's literal passwords in your log files (be it the app logs, or server logs).Hoxie
@DigitalNinja Whatever shared-secret token gets transmitted to the server (not what gets typed into the web page) is the "literal password" for all relevant purposes, including breach disclosure, log files, and other failures. Naively it might seem it improves your "literal passwords" , but situational limitations prevent it from actually helping. Possible downside is you'll act as if this step adds value, and could compromise "real" security when evaluating trade-offs. There is no possible upside as described. Under no scenario is your situation better than without client-side hashing.Flaring
@Flaring It's the literal password for all relevant purposes regarding the site it happens on. But isn't the reason we hash passwords to prevent snoopers from reusing a person's (typed) password in other apps, in case they use the same password on multiple platforms?Hoxie
@DigitalNinja It's been six years since I first asked this question, and I've come to realize that nobody on this page will acknowledge the very specific question of double hashing to protect a user's repeated plaintext password on other sites. Probably because it can't be generalized, so it's not a very interesting question to engage with. To answer your question: Yes, it does help, if 1) the request is MITM'd, 2) the user has reused the password elsewhere, 3) it is a strong password that can't be easily cracked. It's a fairly niche protection, so most don't bother.Spanishamerican
According to GDPR the plain text password is personal data which must not be transmitted before the user has accepted your privacy rules. With a hashed password you are transmitting pseudonymous data, which does not fall under the GDRP privacy rules (as long as you cannot correlate personal data with this password). Also if the hashed password leaks, you do not have a problem with GDPR, as only pseudonymous data leaks. (Same is true for usernames. As usernames must be associated with the password, you need to hash them too to obey to the GDPR, else pseudonymous becomes personal.)Cerallua
Playing around law definitions is not relevant to cryptographic security. Just make a checkbox with a link to EULA as required for the registration form and you are GDPR-compliant now. Leaking client hashes is irrelevant to cryptographic security too. The reason any attacker guesses passwords is not for passwords themselves, but the slew of personal data they unlock. And in this regard ssn used as a password provides no less security than a sha256 hash of it.Halvaard
P
41

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)
Paderewski answered 12/2, 2018 at 1:37 Comment(2)
This should be incorporated in the accepted answer for those who want to use the solution there. (Heck, even their own docs don't have a snippet like this)Reorganization
This is the best answer. I was trying the crypto solution but it didn't work for me.Buffon
C
21

Forge's SHA-256 implementation is fast and reliable.

To run tests on several SHA-256 JavaScript implementations, go to http://brillout.github.io/test-javascript-hash-implementations/.

The results on my machine suggests forge to be the fastest implementation and also considerably faster than the Stanford Javascript Crypto Library (sjcl) mentioned in the accepted answer.

Forge is 256 KB big, but extracting the SHA-256 related code reduces the size to 4.5 KB, see https://github.com/brillout/forge-sha256

Clareta answered 22/7, 2015 at 11:39 Comment(1)
I managed to install it with npm install node-forge, but now, how to use the library do create a hash from the string foo?Hypnogenesis
V
15

No, there's no way to use browser JavaScript to improve password security. I highly recommend you read this article. In your case, the biggest problem is the chicken-egg problem:

What's the "chicken-egg problem" with delivering Javascript cryptography?

If you don't trust the network to deliver a password, or, worse, don't trust the server not to keep user secrets, you can't trust them to deliver security code. The same attacker who was sniffing passwords or reading diaries before you introduce crypto is simply hijacking crypto code after you do.

[...]

Why can't I use TLS/SSL to deliver the Javascript crypto code?

You can. It's harder than it sounds, but you safely transmit Javascript crypto to a browser using SSL. The problem is, having established a secure channel with SSL, you no longer need Javascript cryptography; you have "real" cryptography.

Which leads to this:

The problem with running crypto code in Javascript is that practically any function that the crypto depends on could be overridden silently by any piece of content used to build the hosting page. Crypto security could be undone early in the process (by generating bogus random numbers, or by tampering with constants and parameters used by algorithms), or later (by spiriting key material back to an attacker), or --- in the most likely scenario --- by bypassing the crypto entirely.

There is no reliable way for any piece of Javascript code to verify its execution environment. Javascript crypto code can't ask, "am I really dealing with a random number generator, or with some facsimile of one provided by an attacker?" And it certainly can't assert "nobody is allowed to do anything with this crypto secret except in ways that I, the author, approve of". These are two properties that often are provided in other environments that use crypto, and they're impossible in Javascript.

Basically the problem is this:

  • Your clients don't trust your servers, so they want to add extra security code.
  • That security code is delivered by your servers (the ones they don't trust).

Or alternatively,

  • Your clients don't trust SSL, so they want you use extra security code.
  • That security code is delivered via SSL.

Note: Also, SHA-256 isn't suitable for this, since it's so easy to brute force unsalted non-iterated passwords. If you decide to do this anyway, look for an implementation of bcrypt, scrypt or PBKDF2.

Visitor answered 19/8, 2013 at 22:14 Comment(16)
This is not correct. The password security can be improved by hashing on the client side. It is also wrong that SHA-256 is unsuited as long as something like PBKDF2 is used on the server side. Thirdly, while the matasano article contains useful insight, the punch line is wrong since we now have browser apps that fundamentally change the chicken-and-egg issue.Ileana
@Ileana [citation needed]Visitor
You're right that PBKDF2 should be used on the client. The rage against client side javascript crypto assumes that the initial page and subsequent requests have the same security properties. That is obviously not true for browser apps where the initial page is installed separately and is static. It is also not true for any page with cache-forever semantics. In these cases, it is TOFU which is exactly the same as when installing a client side program. This can also be true in more complex setups where serving of static and dynamic pages are separated on the server.Ileana
@Ileana You have a good point about HTML5 apps that are cached locally (Firefox OS apps for example), but the question is about a forum login, where doing this is completely worthless. I'll update the answer to say "browser JavaScript", because it's true that JavaScript itself isn't the problem.Visitor
It is legitimate to avoid system administrators to have access to user passwords, so hashing in the client side prevent DBAs or other IT professionals to see users passwords and try to reuse it to access other services/systems, since a lot of users repeat their passwords.Gensler
Actually chicken and egg problem can be solved. Server sends a unique "token" User submits/enters password, javascript hashes together token and password, you now have a unique "hash" everytime a password is submitted and the attacker dosen't have the password. The server verifys the password by hashing the information locally "token+password" and compares the outputted hash with the user/browser submitted hash. Any incterception over a SSL/crypto connection is a flaw in the transporation security and not the authentication at this point. problem solved.also any interception is a one timeHardship
@Hardship All you're doing is creating a new password which is "token + password". All of the original problems still apply. For example, an attacker can replace the JavaScript with code to send them the token + password.Visitor
Not so the attacker/intecepter have to beat the "submitting" of the so called "no password" because the receiving server should delete the "new password" after its used, its unlikely that the attack would internept the "new password" and be able to submit it faster than the original sender unless of course they have total control of the victim which the victim has bigger troubles then the proposed solution in placeHardship
It is the chicken and egg senario but my solution is the "sperm that gets their first" is the winner. All other connections/requests from the one that didn't get their first are "dropped" thus effectively reducing/stopping the attack.Hardship
@Hardship The chicken and egg problem doesn't have anything to do with the requests you send. The problem is that your client is using JavaScript code that it downloaded over an insecure connection to do security work. The only way to safely send JavaScript to a web browser is to serve it over TLS, and once you do that, you don't need to do anything else because your connection is already secure. It doesn't matter what your protocol is if you're using JavaScript code that an attacker can just replace.Visitor
@BrendanLong Nowadays you can use subresource integrity. All you have to do is to use a small authentic first page which can be kept local within the URL, then no MitM can fake anything afterwards.Cerallua
The reason you should hash passwords on the client side is NOT to make it more secure as the HTTP request traverses the Internet (TLS already does that). Rather, it's so that the plaintext passwords don't appear in places like the log files on the server middleware. When you have plaintext passwords in server-side log files, then people with access to those log files can make malicious use of them. Most people use the same password for many sites, so if a log file shows "[email protected]" has a password of "Tiger123", that can be used to target other websites that same user might use.Tranquillity
Says "there's no way to use browser JavaScript to improve password security". Non-securely links to an HTTP website for the explanation. ¯_(ツ)_/¯Diacritical
By the same logic there is no need for desktop crypto. The software could have been downloaded form an insecure website and could contain malware like a trojan or a keylogger. And if you got the software through a secure channel, then just get everything through that channel.Diacritical
So, if my server is using HTTPS/TLS2.0, then I should just use cleartext password strings until I need to save them in a backing store? And then on the server I create an HMAC digest using that clear text to store and then compare against new submissions later?Polston
@user1944491 Yes, you should encrypt passwords using TLS if you need to transfer them over the internet to your backend server. You should not use HMAC for password storage, you should use a key derivation function like argon2, bcrypt or PBKDF2. One part of my thinking which has changed here is that hashing on the client side could be useful to prevent accidental logging of passwords, as long as you understand that it's purely an operational benefit and provides approximately no additional security if you're all of the more important steps correctly (TLS).Visitor
S
13

I found this implementation very easy to use. Also has a generous BSD-style license:

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

I needed a quick way to get the hex-string representation of a SHA-256 hash. It only took 3 lines:

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");
Siobhansion answered 2/6, 2016 at 0:28 Comment(0)
U
3

It is possible to use CryptoJS - https://www.npmjs.com/package/crypto-js

import sha256 from 'crypto-js/sha256'

const hash = sha256('Text')
Ugaritic answered 18/1, 2022 at 0:35 Comment(0)
O
2

Besides the Stanford lib that tylerl mentioned. I found jsrsasign very useful (Github repo here:https://github.com/kjur/jsrsasign). I don't know how exactly trustworthy it is, but i've used its API of SHA256, Base64, RSA, x509 etc. and it works pretty well. In fact, it includes the Stanford lib as well.

If all you want to do is SHA256, jsrsasign might be a overkill. But if you have other needs in the related area, I feel it's a good fit.

Oversoul answered 11/12, 2015 at 22:29 Comment(2)
It is safer and faster to use developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_APIPalladio
Agree, but to be fair,I answered this question in 2015 while mozilla's web crypto API specification was published Jan 2017Oversoul
S
2

js-sha256 is an npm package you can use, and unlike the popular crypto.subtle which only works on secure connections(localhost/https) it can work regardless. Of course having a secure connection is still the best. I was using crypto.subtle and it always worked because I run my webapp using localhost and it failed the instant I tried it on a server. I had to switch to the js-sha256 npm package as a temporary solution until a secure connection can be configured.

Sepulchral answered 5/5, 2022 at 9:16 Comment(2)
just forgot, how to install npm i js-sha256; and a sample how to use it const sha256 = require('js-sha256'); hashed = sha256(yourtext);Taxeme
I was looking for an alternative to System.Security.Cryptography.SHA256Managed from C# and this is what I found closestIncrustation
H
1

ethers.js has a SHA256 (https://docs.ethers.io/v5/api/utils/hashing/)

const { ethers } = require('ethers');
ethers.utils.sha256(ethers.utils.toUtf8Bytes('txt'));
Hawthorne answered 16/2, 2022 at 8:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.