UNPKG

14.3 kBMarkdownView Raw
1```
2_________________________________________________/\/\___________________
3_/\/\/\/\/\__/\/\__/\/\____/\/\/\/\__/\/\__/\/\__/\/\________/\/\/\/\___
4_____/\/\______/\/\/\____/\/\________/\/\__/\/\__/\/\/\/\____/\/\__/\/\_
5___/\/\________/\/\/\____/\/\__________/\/\/\____/\/\__/\/\__/\/\__/\/\_
6_/\/\/\/\/\__/\/\__/\/\____/\/\/\/\______/\______/\/\/\/\____/\/\__/\/\_
7________________________________________________________________________
8```
9
10[![Build Status](https://travis-ci.org/dropbox/zxcvbn.svg?branch=master)](https://travis-ci.org/dropbox/zxcvbn)
11[![Sauce Test Status](https://saucelabs.com/browser-matrix/dropbox-zxcvbn.svg)](https://saucelabs.com/u/dropbox-zxcvbn)
12
13`zxcvbn` is a password strength estimator inspired by password crackers. Through pattern matching and conservative estimation, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats (`aaa`), sequences (`abcd`), keyboard patterns (`qwertyuiop`), and l33t speak.
14
15Consider using zxcvbn as an algorithmic alternative to password composition policy — it is more secure, flexible, and usable when sites require a minimal complexity score in place of annoying rules like "passwords must contain three of {lower, upper, numbers, symbols}".
16
17* __More secure__: policies often fail both ways, allowing weak passwords (`P@ssword1`) and disallowing strong passwords.
18* __More flexible__: zxcvbn allows many password styles to flourish so long as it detects sufficient complexity — passphrases are rated highly given enough uncommon words, keyboard patterns are ranked based on length and number of turns, and capitalization adds more complexity when it's unpredictaBle.
19* __More usable__: zxcvbn is designed to power simple, rule-free interfaces that give instant feedback. In addition to strength estimation, zxcvbn includes minimal, targeted verbal feedback that can help guide users towards less guessable passwords.
20
21For further detail and motivation, please refer to the USENIX Security '16 [paper and presentation](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler).
22
23At Dropbox we use zxcvbn ([Release notes](https://github.com/dropbox/zxcvbn/releases)) on our web, desktop, iOS and Android clients. If JavaScript doesn't work for you, others have graciously ported the library to these languages:
24
25* [`zxcvbn-python`](https://github.com/dwolfhub/zxcvbn-python) (Python)
26* [`zxcvbn-cpp`](https://github.com/rianhunter/zxcvbn-cpp) (C/C++/Python/JS)
27* [`zxcvbn-c`](https://github.com/tsyrogit/zxcvbn-c) (C/C++)
28* [`zxcvbn-rs`](https://github.com/shssoichiro/zxcvbn-rs) (Rust)
29* [`zxcvbn-go`](https://github.com/nbutton23/zxcvbn-go) (Go)
30* [`zxcvbn4j`](https://github.com/nulab/zxcvbn4j) (Java)
31* [`nbvcxz`](https://github.com/GoSimpleLLC/nbvcxz) (Java)
32* [`zxcvbn-ruby`](https://github.com/envato/zxcvbn-ruby) (Ruby)
33* [`zxcvbn-js`](https://github.com/bitzesty/zxcvbn-js) (Ruby [via ExecJS])
34* [`zxcvbn-ios`](https://github.com/dropbox/zxcvbn-ios) (Objective-C)
35* [`zxcvbn-cs`](https://github.com/mickford/zxcvbn-cs) (C#/.NET)
36* [`szxcvbn`](https://github.com/tekul/szxcvbn) (Scala)
37* [`zxcvbn-php`](https://github.com/bjeavons/zxcvbn-php) (PHP)
38* [`zxcvbn-api`](https://github.com/wcjr/zxcvbn-api) (REST)
39
40Integrations with other frameworks:
41* [`angular-zxcvbn`](https://github.com/ghostbar/angular-zxcvbn) (AngularJS)
42
43# Installation
44
45zxcvbn detects and supports CommonJS (node, browserify) and AMD (RequireJS). In the absence of those, it adds a single function `zxcvbn()` to the global namespace.
46
47## Bower
48
49Install [`node`](https://nodejs.org/download/) and [`bower`](http://bower.io/) if you haven't already.
50
51Get `zxcvbn`:
52
53``` shell
54cd /path/to/project/root
55bower install zxcvbn
56```
57
58Add this script to your `index.html`:
59
60``` html
61<script src="bower_components/zxcvbn/dist/zxcvbn.js">
62</script>
63```
64
65To make sure it loaded properly, open in a browser and type `zxcvbn('Tr0ub4dour&3')` into the console.
66
67To pull in updates and bug fixes:
68
69``` shell
70bower update zxcvbn
71```
72
73## Node / npm / MeteorJS
74
75zxcvbn works identically on the server.
76
77``` shell
78$ npm install zxcvbn
79$ node
80> var zxcvbn = require('zxcvbn');
81> zxcvbn('Tr0ub4dour&3');
82```
83
84## RequireJS
85
86Add [`zxcvbn.js`](https://raw.githubusercontent.com/dropbox/zxcvbn/master/dist/zxcvbn.js) to your project (using bower, npm or direct download) and import as usual:
87
88``` javascript
89requirejs(["relpath/to/zxcvbn"], function (zxcvbn) {
90 console.log(zxcvbn('Tr0ub4dour&3'));
91});
92```
93
94## Browserify / Webpack
95
96If you're using `npm` and have `require('zxcvbn')` somewhere in your code, browserify and webpack should just work.
97
98``` shell
99$ npm install zxcvbn
100$ echo "console.log(require('zxcvbn'))" > mymodule.js
101$ browserify mymodule.js > browserify_bundle.js
102$ webpack mymodule.js webpack_bundle.js
103```
104
105But we recommend against bundling zxcvbn via tools like browserify and webpack, for three reasons:
106
107* Minified and gzipped, zxcvbn is still several hundred kilobytes. (Significantly grows bundle size.)
108* Most sites will only need zxcvbn on a few pages (registration, password reset).
109* Most sites won't need `zxcvbn()` immediately upon page load; since `zxcvbn()` is typically called in response to user events like filling in a password, there's ample time to fetch `zxcvbn.js` after initial html/css/js loads and renders.
110
111See the [performance](#perf) section below for tips on loading zxcvbn stand-alone.
112
113Tangentially, if you want to build your own standalone, consider tweaking the browserify pipeline used to generate `dist/zxcvbn.js`:
114
115``` shell
116$ browserify --debug --standalone zxcvbn \
117 -t coffeeify --extension='.coffee' \
118 -t uglifyify \
119 src/main.coffee | exorcist dist/zxcvbn.js.map >| dist/zxcvbn.js
120```
121
122* `--debug` adds an inline source map to the bundle. `exorcist` pulls it out into `dist/zxcvbn.js.map`.
123* `--standalone zxcvbn` exports a global `zxcvbn` when CommonJS/AMD isn't detected.
124* `-t coffeeify --extension='.coffee'` compiles `.coffee` to `.js` before bundling. This is convenient as it allows `.js` modules to import from `.coffee` modules and vice-versa. Instead of this transform, one could also compile everything to `.js` first (`npm run prepublish`) and point `browserify` to `lib` instead of `src`.
125* `-t uglifyify` minifies the bundle through UglifyJS, maintaining proper source mapping.
126
127## Manual installation
128
129Download [zxcvbn.js](https://raw.githubusercontent.com/dropbox/zxcvbn/master/dist/zxcvbn.js).
130
131Add to your .html:
132
133``` html
134<script type="text/javascript" src="path/to/zxcvbn.js"></script>
135```
136
137# Usage
138
139[try zxcvbn interactively](https://dl.dropboxusercontent.com/u/209/zxcvbn/test/index.html) to see these docs in action.
140
141``` javascript
142zxcvbn(password, user_inputs=[])
143```
144
145`zxcvbn()` takes one required argument, a password, and returns a result object with several properties:
146
147``` coffee
148result.guesses # estimated guesses needed to crack password
149result.guesses_log10 # order of magnitude of result.guesses
150
151result.crack_times_seconds # dictionary of back-of-the-envelope crack time
152 # estimations, in seconds, based on a few scenarios:
153{
154 # online attack on a service that ratelimits password auth attempts.
155 online_throttling_100_per_hour
156
157 # online attack on a service that doesn't ratelimit,
158 # or where an attacker has outsmarted ratelimiting.
159 online_no_throttling_10_per_second
160
161 # offline attack. assumes multiple attackers,
162 # proper user-unique salting, and a slow hash function
163 # w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.
164 offline_slow_hashing_1e4_per_second
165
166 # offline attack with user-unique salting but a fast hash
167 # function like SHA-1, SHA-256 or MD5. A wide range of
168 # reasonable numbers anywhere from one billion - one trillion
169 # guesses per second, depending on number of cores and machines.
170 # ballparking at 10B/sec.
171 offline_fast_hashing_1e10_per_second
172}
173
174result.crack_times_display # same keys as result.crack_times_seconds,
175 # with friendlier display string values:
176 # "less than a second", "3 hours", "centuries", etc.
177
178result.score # Integer from 0-4 (useful for implementing a strength bar)
179
180 0 # too guessable: risky password. (guesses < 10^3)
181
182 1 # very guessable: protection from throttled online attacks. (guesses < 10^6)
183
184 2 # somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
185
186 3 # safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
187
188 4 # very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
189
190result.feedback # verbal feedback to help choose better passwords. set when score <= 2.
191
192 result.feedback.warning # explains what's wrong, eg. 'this is a top-10 common password'.
193 # not always set -- sometimes an empty string
194
195 result.feedback.suggestions # a possibly-empty list of suggestions to help choose a less
196 # guessable password. eg. 'Add another word or two'
197
198result.sequence # the list of patterns that zxcvbn based the
199 # guess calculation on.
200
201result.calc_time # how long it took zxcvbn to calculate an answer,
202 # in milliseconds.
203````
204
205The optional `user_inputs` argument is an array of strings that zxcvbn will treat as an extra dictionary. This can be whatever list of strings you like, but is meant for user inputs from other fields of the form, like name and email. That way a password that includes a user's personal information can be heavily penalized. This list is also good for site-specific vocabulary — Acme Brick Co. might want to include ['acme', 'brick', 'acmebrick', etc].
206
207# <a name="perf"></a>Performance
208
209## runtime latency
210
211zxcvbn operates below human perception of delay for most input: ~5-20ms for ~25 char passwords on modern browsers/CPUs, ~100ms for passwords around 100 characters. To bound runtime latency for really long passwords, consider sending `zxcvbn()` only the first 100 characters or so of user input.
212
213## script load latency
214
215`zxcvbn.js` bundled and minified is about 400kB gzipped or 820kB uncompressed, most of which is dictionaries. Consider these tips if you're noticing page load latency on your site.
216
217* Make sure your server is configured to compress static assets for browsers that support it. ([nginx tutorial](https://rtcamp.com/tutorials/nginx/enable-gzip/), [Apache/IIS tutorial](http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/).)
218
219Then try one of these alternatives:
220
2211. Put your `<script src="zxcvbn.js">` tag at the end of your html, just before the closing `</body>` tag. This insures your page loads and renders before the browser fetches and loads `zxcvbn.js`. The downside with this approach is `zxcvbn()` becomes available later than had it been included in `<head>` — not an issue on most signup pages where users are filling out other fields first.
222
2232. If you're using RequireJS, try loading `zxcvbn.js` separately from your main bundle. Something to watch out for: if `zxcvbn.js` is required inside a keyboard handler waiting for user input, the entire script might be loaded only after the user presses their first key, creating nasty latency. Avoid this by calling your handler once upon page load, independent of user input, such that the `requirejs()` call runs earlier.
224
2253. Use the HTML5 [`async`](http://www.w3schools.com/tags/att_script_async.asp) script attribute. Downside: [doesn't work](http://caniuse.com/#feat=script-async) in IE7-9 or Opera Mini.
226
2274. Include an inline `<script>` in `<head>` that asynchronously loads `zxcvbn.js` in the background. Advantage over (3): it works in older browsers.
228
229``` javascript
230// cross-browser asynchronous script loading for zxcvbn.
231// adapted from http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
232
233(function() {
234
235 var ZXCVBN_SRC = 'path/to/zxcvbn.js';
236
237 var async_load = function() {
238 var first, s;
239 s = document.createElement('script');
240 s.src = ZXCVBN_SRC;
241 s.type = 'text/javascript';
242 s.async = true;
243 first = document.getElementsByTagName('script')[0];
244 return first.parentNode.insertBefore(s, first);
245 };
246
247 if (window.attachEvent != null) {
248 window.attachEvent('onload', async_load);
249 } else {
250 window.addEventListener('load', async_load, false);
251 }
252
253}).call(this);
254```
255
256# Development
257
258Bug reports and pull requests welcome!
259
260``` shell
261git clone https://github.com/dropbox/zxcvbn.git
262```
263
264zxcvbn is built with CoffeeScript, browserify, and uglify-js. CoffeeScript source lives in `src`, which gets compiled, bundled and minified into `dist/zxcvbn.js`.
265
266``` shell
267npm run build # builds dist/zxcvbn.js
268npm run watch # same, but quickly rebuilds as changes are made in src.
269```
270
271For debugging, both `build` and `watch` output an external source map `dist/zxcvbn.js.map` that points back to the original CoffeeScript code.
272
273Two source files, `adjacency_graphs.coffee` and `frequency_lists.coffee`, are generated by python scripts in `data-scripts` that read raw data from the `data` directory.
274
275For node developers, in addition to `dist`, the zxcvbn `npm` module includes a `lib` directory (hidden from git) that includes one compiled `.js` and `.js.map` file for every `.coffee` in `src`. See `prepublish` in `package.json` to learn more.
276
277# Acknowledgments
278
279[Dropbox](https://dropbox.com) for supporting open source!
280
281Mark Burnett for releasing his 10M password corpus and for his 2005 book, [Perfect Passwords: Selection, Protection, Authentication](http://www.amazon.com/Perfect-Passwords-Selection-Protection-Authentication/dp/1597490415).
282
283Wiktionary contributors for building a [frequency list of English words](http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists) as used in television and movies.
284
285Researchers at Concordia University for [studying password estimation rigorously](http://www.concordia.ca/cunews/main/stories/2015/03/25/does-your-password-pass-muster.html) and recommending zxcvbn.
286
287And [xkcd](https://xkcd.com/936/) for the inspiration :+1::horse::battery::heart: