zxcvbn4j

repository·main·Indexed 18 days ago

https://github.com/nulab/zxcvbn4j

A Java implementation of the zxcvbn password strength estimator. It assesses password strength using pattern matching, dictionary checks, and common pattern detection, including support for over 30,000 common passwords, US census names, and keyboard layouts like JIS and QWERTY. It provides detailed metrics via a Strength object, including crack time estimations and a score from 0-4, and supports localization of feedback messages into multiple languages including English, Japanese, Dutch, German, French, Italian, Spanish, and Portuguese.

Tokens
4.2K
Snippets
8
Records
12
Agent score
63%

What's inside zxcvbn4j

  1. Overview of zxcvbn4j features

    main

    zxcvbn4j is a Java port of the Dropbox zxcvbn password strength estimator. It uses pattern matching and conservative estimation to assess password strength by identifying:

    • Over 30,000 common passwords.
    • Common names and surnames (based on US census data).
    • Popular English words from Wikipedia, US TV shows, and movies.
    • Common patterns like dates, repeated characters (aaa), sequences (abcd), keyboard patterns (qwertyuiop), and l33t speak.

    Key capabilities:

    • Customization: Customize internal dictionaries and keyboard layouts.
    • Localization: Localize feedback messages into multiple supported languages.
    • Keyboard Support: Includes support for the JIS keyboard layout.
    • Flexible Input: Accepts passwords as CharSequence or String to improve security and flexibility.
  2. Localize feedback messages using ResourceBundle

    main

    By default, zxcvbn4j returns feedback messages in English. You can localize these messages (such as warnings and suggestions) into other languages using ResourceBundle.

    Option 1: Localize a single Feedback instance

    Use Feedback.withResourceBundle(ResourceBundle) to create a new Feedback instance where getSuggestions() and getWarning() return localized strings based on the provided bundle.

    Option 2: Localize using a Map of Locales

    Use Feedback.replaceResourceBundle(Map<Locale, ResourceBundle>) to provide a mapping of multiple locales to their respective bundles. This allows the feedback to adapt based on the locale provided.

    When creating your property files, refer to the existing messages.properties in the repository for the required key/message structure.

    // Option 1: Localize a single Feedback instance
    Zxcvbn zxcvbn = new Zxcvbn();
    Strength strength = zxcvbn.measure("This is password");
    ResourceBundle resourceBundle = ResourceBundle.getBundle("This is bundle name", Locale.JAPAN);
    
    Feedback feedback = strength.getFeedback();
    Feedback localizedFeedback = feedback.withResourceBundle(resourceBundle);
    
    List<String> localizedSuggestions = localizedFeedback.getSuggestions();
    String localizedWarning = localizedFeedback.getWarning();
    
    // Option 2: Localize using a Map of Locales
    Map<Locale, ResourceBundle> messages = new HashMap<>();
    messages.put(Locale.JAPANESE, ResourceBundle.getBundle("This is bundle name", Locale.JAPANESE));
    messages.put(Locale.ITALIAN, ResourceBundle.getBundle("This is bundle name", Locale.ITALIAN));
    Feedback replacedFeedback = feedback.replaceResourceBundle(messages);
  3. Customize dictionaries and keyboards with ZxcvbnBuilder

    main

    Use ZxcvbnBuilder to customize the internal dictionaries and keyboards used during measurement. You can load resources from the classpath, from files, or via HTTP by implementing the Resource interface.

    Load from Classpath

    Use ClasspathResource with DictionaryLoader, SlantedKeyboardLoader, or AlignedKeyboardLoader.

    Load from Files

    Implement the Resource interface to wrap a File or URL and provide an InputStream via getInputStream().

    Use Default Resources

    • StandardDictionaries.loadAllDictionaries(): Loads all default dictionaries.
    • StandardKeyboards.loadAllKeyboards(): Loads all default keyboards.
    • You can also select specific loaders like StandardDictionaries.ENGLISH_WIKIPEDIA_LOADER.load().
    // Example: Loading custom resources from classpath
    Zxcvbn zxcvbn = new ZxcvbnBuilder()
            .dictionary(new DictionaryLoader("us_tv_and_film", new ClasspathResource("/com/nulabinc/zxcvbn/matchers/dictionarys/us_tv_and_film.txt")).load())
            .keyboard(new SlantedKeyboardLoader("qwerty", new ClasspathResource("/com/nulabinc/zxcvbn/matchers/keyboards/qwerty.txt")).load())
            .build();
    
    // Example: Using specific default resources
    Zxcvbn zxcvbn = new ZxcvbnBuilder()
        .dictionary(StandardDictionaries.ENGLISH_WIKIPEDIA_LOADER.load())
        .dictionary(StandardDictionaries.PASSWORDS_LOADER.load())
        .keyboard(StandardKeyboards.QWERTY_LOADER.load())
        .build();
  4. Localize feedback messages

    main

    You can translate the English feedback messages (warnings and suggestions) into other languages using Java ResourceBundle.

    Localize a single feedback instance

    1. Get the Strength object.
    2. Get the Feedback object from strength.getFeedback().
    3. Create a ResourceBundle for your target Locale.
    4. Call feedback.withResourceBundle(resourceBundle) to get a new Feedback instance with localized strings.

    Localize multiple locales at once

    Use feedback.replaceResourceBundle(Map<Locale, ResourceBundle> messages) to replace the feedback with a map of pre-loaded bundles for different locales.

    // Localize a single feedback
    Zxcvbn zxcvbn = new Zxcvbn();
    Strength strength = zxcvbn.measure("This is password");
    ResourceBundle resourceBundle = ResourceBundle.getBundle("This is bundle name", Locale.JAPAN);
    
    Feedback feedback = strength.getFeedback();
    Feedback localizedFeedback = feedback.withResourceBundle(resourceBundle);
    
    List<String> localizedSuggestions = localizedFeedback.getSuggestions();
    String localizedWarning = localizedFeedback.getWarning();
    
    // Replace multiple locales
    Map<Locale, ResourceBundle> messages = new HashMap<>();
    messages.put(Locale.JAPANESE, ResourceBundle.getBundle("This is bundle name", Locale.JAPANESE));
    messages.put(Locale.ITALIAN, ResourceBundle.getBundle("This is bundle name", Locale.ITALIAN));
    Feedback replacedFeedback = feedback.replaceResourceBundle(messages);
  5. Measure password strength with Zxcvbn

    main

    To perform basic password strength measurement, instantiate Zxcvbn and call the measure method. This works on standard Java environments and Android.

    If you want to include specific user-provided keywords (like company names or common user terms) to increase the sensitivity of the measurement, pass a List<String> as the second argument to measure.

    Zxcvbn zxcvbn = new Zxcvbn();
    Strength strength = zxcvbn.measure("This is password");
    
    // With custom sanitized inputs
    List<String> sanitizedInputs = new ArrayList<>();
    sanitizedInputs.add("nulab");
    sanitizedInputs.add("backlog");
    
    Zxcvbn zxcvbn = new Zxcvbn();
    Strength strength = zxcvbn.measure("This is password", sanitizedInputs);
  6. Install zxcvbn4j via Maven or Gradle

    main

    You can add zxcvbn4j to your project using Maven or Gradle. The library is available on Maven Central.

    Gradle:

    compile 'com.nulab-inc:zxcvbn:1.9.0'

    Maven:

    <dependency>
      <groupId>com.nulab-inc</groupId>
      <artifactId>zxcvbn</artifactId>
      <version>1.9.0</version>
    </dependency>
  7. Customize dictionaries and keyboards using ZxcvbnBuilder

    main

    Use ZxcvbnBuilder to customize the dictionaries and keyboard layouts used by the measurement engine. You can load resources from the classpath, local files, or via HTTP by implementing the Resource interface.

    Loading from Classpath

    Use ClasspathResource with DictionaryLoader, SlantedKeyboardLoader, or AlignedKeyboardLoader.

    Loading from Files

    Implement a Resource that returns an InputStream from a File or URL.

    Using Default Resources

    • To use all default resources: new Zxcvbn() or use StandardDictionaries.loadAllDictionaries() and StandardKeyboards.loadAllKeyboards() with the builder.
    • To select specific defaults: Use loaders like StandardDictionaries.ENGLISH_WIKIPEDIA_LOADER.load() or StandardKeyboards.QWERTY_LOADER.load().
    // Example: Loading from Classpath
    Zxcvbn zxcvbn = new ZxcvbnBuilder()
            .dictionary(new DictionaryLoader("us_tv_and_film", new ClasspathResource("/com/nulabinc/zxcvbn/matchers/dictionarys/us_tv_and_film.txt")).load())
            .keyboard(new SlantedKeyboardLoader("qwerty", new ClasspathResource("/com/nulabinc/zxcvbn/matchers/keyboards/qwerty.txt")).load())
            .build();
    
    // Example: Selecting specific default resources
    Zxcvbn zxcvbn = new ZxcvbnBuilder()
        .dictionary(StandardDictionaries.ENGLISH_WIKIPEDIA_LOADER.load())
        .dictionary(StandardDictionaries.PASSWORDS_LOADER.load())
        .keyboard(StandardKeyboards.QWERTY_LOADER.load())
        .keyboard(StandardKeyboards.DVORAK_LOADER.load())
        .build();
  8. Understand the Strength return object properties

    main

    The measure method returns a Strength object containing detailed metrics about the password's security. Key properties include:

    • guesses: Estimated guesses needed to crack the password.
    • guessesLog10: Order of magnitude of guesses.
    • crackTimeSeconds: A dictionary of crack time estimations in seconds for different scenarios:
      • onlineThrottling100PerHour: Online attack with rate limiting.
      • onlineNoThrottling10PerSecond: Online attack without rate limiting.
      • offlineSlowHashing1e4PerSecond: Offline attack with moderate work factor (e.g., bcrypt).
      • offlineFastHashing1e10PerSecond: Offline attack with fast hash functions (e.g., MD5, SHA-1).
    • crackTimeDisplay: Human-readable strings for crack times (e.g., "3 hours", "centuries").
    • score: An integer from 0-4 used for strength bars:
      • 0: Weak
      • 1: Fair
      • 2: Good
      • 3: Strong
      • 4: Very strong
    • feedback: Contains warning (string) and suggestions (list of strings) to help users improve passwords. Usually provided when score <= 2.
    • sequence: The list of patterns used for the calculation.
    • calc_time: Time taken for calculation in milliseconds.
  9. Supported languages for feedback localization

    main

    zxcvbn4j provides default support for the following languages. You can use these to localize the feedback messages returned by the estimator:

    • English (default)
    • Japanese (ja)
    • Dutch (nl)
    • German (de)
    • French (fr)
    • Italian (it)
    • Spanish (es)
    • Portuguese (pt)
  10. Understand the Strength output

    main

    The measure method returns a Strength instance containing detailed metrics about the password's security. Key fields include:

    • guesses: Number of guesses required to crack the password.
    • guessesLog10: Log10 of the number of guesses.
    • crackTimeSeconds: A map containing estimated crack times for different scenarios:
      • onlineThrottling100PerHour: Online attack with 100 attempts/hour limit.
      • onlineNoThrottling10PerSecond: Online attack with 10 attempts/second limit.
      • offlineSlowHashing1e4PerSecond: Offline attack using slow hashing (e.g., bcrypt, scrypt, PBKDF2) at 10,000/sec.
      • offlineFastHashing1e10PerSecond: Offline attack using fast hashing (e.g., SHA-1, SHA-256, MD5) at 10,000,000,000/sec.
    • crackTimeDisplay: A human-readable string of the crack time (e.g., "3 hours", "a century").
    • score: An integer from 0 to 4 representing strength:
      • 0: Weak (guesses < 10^3 + 5)
      • 1: Somewhat weak (guesses < 10^6 + 5)
      • 2: Normal (guesses < 10^8 + 5)
      • 3: Strong (guesses < 10^10 + 5)
      • 4: Very strong (guesses >= 10^10 + 5)
    • warning: A warning message (only populated if score <= 2).
    • suggestions: A list of suggestions to improve the password (only populated if score <= 2).
    • sequence: A list of patterns detected during measurement.
    • calc_time: Time taken to perform the calculation.
  11. Create feedback from matches using FeedbackFactory

    main

    The FeedbackFactory class provides static methods to generate Feedback objects based on password strength matches. This is useful for translating internal match data (like dictionary hits or keyboard patterns) into human-readable warnings and suggestions.

    Key methods:

    • createMatchFeedback(Match match, boolean isSoleMatch): The primary entry point. It inspects the Match object's pattern (e.g., Dictionary, Spatial, Repeat, Sequence, Regex, Date) and returns a Feedback object containing appropriate warnings and suggestions.
    • getFeedbackWithoutWarnings(String... suggestions): Creates a Feedback object that contains only the provided suggestions and no warning message.
    • getEmptyFeedback(): Returns a Feedback object with no warnings and no suggestions.
    // Note: FeedbackFactory is package-private in the source, 
    // but its static methods are the intended way to generate feedback 
    // from Match objects in the zxcvbn4j workflow.
    
    Feedback feedback = FeedbackFactory.createMatchFeedback(match, isSoleMatch);
    String warning = feedback.getWarning();
    List<String> suggestions = feedback.getSuggestions();
  12. Create a default password strength estimation context with StandardContext.build()

    main

    To initialize a Context with the standard set of dictionaries and keyboard layouts, use the StandardContext.build() method. This method loads all default dictionaries and keyboards provided by the library and returns a new Context instance ready for use with the zxcvbn estimator.

    Note that StandardContext cannot be instantiated directly; you must use the build() factory method.

    import com.nulabinc.zxcvbn.StandardContext;
    import com.nulabinc.zxcvbn.Context;
    import java.io.IOException;
    
    // ...
    
    try {
        Context context = StandardContext.build();
        // Use the context to estimate password strength
    } catch (IOException e) {
        // Handle errors loading default dictionaries or keyboards
        e.printStackTrace();
    }