10

I have a website and my users will be using their selected password to encrypt their RSA private key using JavaScript client-side. How should I be making sure they are using a strong password without transmitting it to the server?

  • 5
    What makes a "strong" password to you? Have you seen all those "password strength checkers" on websites you've used? Those are all client-side. – schroeder Nov 14 at 15:36
  • 2
    Rather than try to estimate password entropy, consider providing users with a strong way to choose passwords automatically which they can then write down, like ten diceware words from a user-selectable choice of a handful of word lists. – Squeamish Ossifrage Nov 14 at 16:30
  • It depends if you trust your users to execute the JavaScript code you send them as intended. Clients can override client-side protections. If you can't trust them, then you don't have a way to do this except brute forcing with known passwords to test if it's any of those. – meneldal Nov 15 at 1:44
  • 3
    You should read Peter Gutmann's Engineering Security before you go further. In particular, Chapter 7 on Password Security. Pay attention to the discussion of Bloom Filters and weak/wounded password lists. The filtered password list will be small - around 60 KB - and easy to send to a client via JavaScript. You can find weak/wounded password lists at SecLists on GitHub. – user221686 Nov 15 at 3:33
26

You can use zxcvbn, which is a JavaScript library that checks password strength.

Alternatively, the HaveIBeenPwned API takes an interesting approach to check passwords without sending the password to the server:

  • Take a SHA1 hash of the password.
  • Truncate it to five characters.
  • Send this to the server.
  • The server returns the full SHA1 hashes of all known (insecure) passwords with these five characters at the start of their hash.
  • The client checks whether the password hash is in this list.

This way, you don't submit the whole password but the client also doesn't need to retrieve the whole password database.

  • 7
    zxcvbn has it's flaws too, and renders it quite pointless. For instance, it would consider MakeAmericaGreatAgain to be a relatively secure password, even though you and me both know it probably isn't. – MechMK1 Nov 14 at 14:42
  • 4
    @mark820850 The idea behind hveIBeenPawned is that it is very cheap for an attacker to check all of those hashes looking for low hanging fruit. If you crack a server enough to get a list of encrypted passwords, you can see if any of them just happen to be the poor choices, and then log in with those. In the same vein, it was common to check whether the password was "password" or "password1", given how cheap that attack was to execute compared to how often it succeeded. – Cort Ammon - Reinstate Monica Nov 14 at 14:58
  • 1
    @mark820850 HaveIBeenPwned (HIBP) works off of having a gigantic list of leaked passwords. They have MD5 hashes of all of those leaked passwords. You send up the first 5 characters of your MD5 hash, and they return a list of all password hashes they have that start with those same 5 characters (typically ~100 hashes). As a result you will get back many hashes for completely unrelated passwords. However, if you find a hash that matches your hash, you know that they have that password in their database and therefore that password has been leaked previously. – Conor Mancone Nov 14 at 16:00
  • 1
    The idea is that if a password has showed up in a previous password dump it is no longer a secure password. Therefore they aren't measuring password strength exactly, but trying to more directly determine if a password is known to be unsafe. They have you send the first 5 letters of the hash because this way you don't actually send around your user's passwords, so this is effectively a private way of checking passwords against a database of leaked passwords. – Conor Mancone Nov 14 at 16:01
  • 1
    @Peteris My comments aren't meant to be an endorsement of HIBP, simply because it isn't the best solution for everyone. In general though I do think it is good advice to avoid passwords that have been in a breach. My suggestion for users that want a memorable password and don't use managers would be to use a pass phrase. Even if it is just 4 words and an actual sentence (i.e. much weaker than diceware), as long as it is 12+ characters long it will probably still be a better password than whatever they were using before. – Conor Mancone Nov 15 at 13:57
9

My go-to for passphrase strength questions is NIST SP 800-63b: "Digital Identity Guidelines: Authentication and Lifecycle Management". While this is a US Gov standard, it also serves as sound guidance for the rest of us.

5.1.1.2 Memorized Secret Verifiers

...

When processing requests to establish and change memorized secrets, verifiers SHALL compare the prospective secrets against a list that contains values known to be commonly-used, expected, or compromised. For example, the list MAY include, but is not limited to:

  • Passwords obtained from previous breach corpuses.

  • Dictionary words.

  • Repetitive or sequential characters (e.g. ‘aaaaaa’, ‘1234abcd’).

  • Context-specific words, such as the name of the service, the username, and derivatives thereof.

If the chosen secret is found in the list, the CSP or verifier SHALL advise the subscriber that they need to select a different secret, SHALL provide the reason for rejection, and SHALL require the subscriber to choose a different value.

Verifiers SHOULD offer guidance to the subscriber, such as a password-strength meter[Meters], to assist the user in choosing a strong memorized secret. This is particularly important following the rejection of a memorized secret on the above list as it discourages trivial modification of listed (and likely very weak) memorized secrets[Blacklists].

Notice how they suggest using strength meters (like zxcvbn) simply as a UI aid, but the actual enforcement is done against a blacklist.

In my experience, the best way to implement this is use a client-side (javascript) entropy-based strength meter like zxcvbn to help the user weed out obviously-weak passphrases. Then when they click Submit, do a REST call to a blacklist database like HaveIBeenPwned. Note that the HaveIBeenPwned API has been designed to avoid leaking the user's actual password, even to the HaveIBeenPwned admins, as @Sjoerd describes nicely in their answer.

  • 3
    I'm also glad NIST dropped the "uppercase, lowercase, number, symbols" stuff. Password length is the key thing from an entropy standpoint - the longer a minimum your users can stomach, the better (NIST says 8 as a minimum). Filter out sequences (alpha, numeric, keyboard), use a top-XXXX list of most common passwords (and filter those out), – Joe Nov 14 at 18:14
  • 1
    Yeah, we had to build our own using lists on the internet and we do it via a round-trip to the back-end. – Joe Nov 15 at 3:16
  • 1
    Why not just disallow any password on the list? After all, that is what the standard you posted suggests, and personally I wouldn't want to use a password even if it had only been leaked once. – Conor Mancone Nov 15 at 13:50
  • 1
    None of my old (now unused) passwords have been pwned, although my old passwords are strong enough and unique enough to me that I wouldn't expect them to be leaked unless the password had specifically been stolen from one of my own accounts. However, definitely don't use billybob (the first random dumb password I tried) - been leaked about 30,000 times. That's gotta be an "USA-only" thing... – Conor Mancone Nov 15 at 18:54
  • 1
    @ConorMancone and Mike, I'm citing your conversation as part of this other question that may be of interest. – Michael Nov 15 at 21:49
5

Measuring password entropy is not an easy task, and basically not even feasible to do. Any system or measurement can be circumvented if tried hard enough. If users really wanted, they could probably even get away with using something like 💩.

It's much better to give user guidelines on how to pick a good password, such as:

It is recommended to use a password manager to generate a long, random password and store it in a safe place.

If using a password manager is not possible, it's encouraged to use Diceware to generate a sufficiently good password.

... And so on and so forth ...

  • 6
    ‘Measuring’ entropy given a single password is not merely hard but meaningless, without a parametric model for the procedure used to choose the password. However, there is a reasonable question of whether the intervention of displaying a password strength meter (whatever model of strength underlies it, if any coherent model!) has the effect of convincing people to use better password-generation procedures. The effect of this intervention is hard to measure, of course! But it's not a priori clear that strength meters—while conceptually absurd—fail to have a useful effect. – Squeamish Ossifrage Nov 15 at 4:59
1

"password strength" is not a clearly defined metric. And when implementing such a checker, please do keep in mind that most libraries still implement the outdated and wrong old NIST guidelines (special characters, numbers, that nonsense).

The strongest indicator of password strength is length. Requiring a reasonably high minimum length, which (2019) is around 12 characters or 16 for important things, is the strongest single check you can have. Mike already included the relevant NIST recommendations for more details.

If you use a library, choose one that implements the current NIST guidelines, not the old ones.

  • 1
    This seems better as a side bit of advice and not an answer to the question about how to do it. – schroeder Nov 15 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.