From d757e4d701f4c42fd7814d177618e774eca7fe23 Mon Sep 17 00:00:00 2001 From: Philipp von Weitershausen Date: Thu, 23 Sep 2010 02:04:31 +0200 Subject: [PATCH] Bug 592465 - Show a passphrase strength meter for custom passphrases [r=mconnor] --- services/sync/modules/util.js | 32 +++++++++++++++++++ services/sync/services-sync.js | 1 + .../sync/tests/unit/test_utils_passphrase.js | 16 ++++++++++ 3 files changed, 49 insertions(+) diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index 922bb6e8c8fb..0de51b54a6a4 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -861,6 +861,38 @@ let Utils = { return pp; }, + /* + * Calculate the strength of a passphrase provided by the user + * according to the NIST algorithm (NIST 800-63 Appendix A.1). + */ + passphraseStrength: function passphraseStrength(value) { + let bits = 0; + + // The entropy of the first character is taken to be 4 bits. + if (value.length) + bits = 4; + + // The entropy of the next 7 characters are 2 bits per character. + if (value.length > 1) + bits += Math.min(value.length - 1, 7) * 2; + + // For the 9th through the 20th character the entropy is taken to + // be 1.5 bits per character. + if (value.length > 8) + bits += Math.min(value.length - 8, 12) * 1.5; + + // For characters 21 and above the entropy is taken to be 1 bit per character. + if (value.length > 20) + bits += value.length - 20; + + // Bonus of 6 bits if we find non-alphabetic characters + if ([char.charCodeAt() for each (char in value.toLowerCase())] + .some(function(chr) chr < 97 || chr > 122)) + bits += 6; + + return bits; + }, + /** * Create an array like the first but without elements of the second */ diff --git a/services/sync/services-sync.js b/services/sync/services-sync.js index 01afdb57b693..13a3fd5d2381 100644 --- a/services/sync/services-sync.js +++ b/services/sync/services-sync.js @@ -4,6 +4,7 @@ pref("services.sync.userURL", "user/"); pref("services.sync.miscURL", "misc/"); pref("services.sync.termsURL", "https://services.mozilla.com/tos/"); pref("services.sync.privacyURL", "https://services.mozilla.com/privacy-policy/"); +pref("services.sync.syncKeyHelpURL", "https://services.mozilla.com/help/synckey"); pref("services.sync.lastversion", "firstrun"); pref("services.sync.autoconnect", true); diff --git a/services/sync/tests/unit/test_utils_passphrase.js b/services/sync/tests/unit/test_utils_passphrase.js index f0ef5dee7375..e561d221ffd0 100644 --- a/services/sync/tests/unit/test_utils_passphrase.js +++ b/services/sync/tests/unit/test_utils_passphrase.js @@ -22,4 +22,20 @@ function run_test() { _("Normalize passphrase recognizes hyphens."); do_check_eq(Utils.normalizePassphrase(hyphenated), pp); do_check_eq(pp, pp); + + _("Passphrase strength calculated according to the NIST algorithm."); + do_check_eq(Utils.passphraseStrength(""), 0); + do_check_eq(Utils.passphraseStrength("a"), 4); + do_check_eq(Utils.passphraseStrength("ab"), 6); + do_check_eq(Utils.passphraseStrength("abc"), 8); + do_check_eq(Utils.passphraseStrength("abcdefgh"), 18); + do_check_eq(Utils.passphraseStrength("abcdefghi"), 19.5); + do_check_eq(Utils.passphraseStrength("abcdefghij"), 21); + do_check_eq(Utils.passphraseStrength("abcdefghijklmnopqrst"), 36); + do_check_eq(Utils.passphraseStrength("abcdefghijklmnopqrstu"), 37); + do_check_eq(Utils.passphraseStrength("abcdefghijklmnopqrstuvwxyz"), 42); + do_check_eq(Utils.passphraseStrength("abcdefghijklmnopqrstuvwxyz!"), 49); + do_check_eq(Utils.passphraseStrength("1"), 10); + do_check_eq(Utils.passphraseStrength("12"), 12); + do_check_eq(Utils.passphraseStrength("a1"), 12); }