Passphrase Meter for Android Apps

Installation

To get Wultra Passphrase Meter for Android up and running in your app, add following dependency in your gradle.build file:

repositories {
    mavenCentral() // if not defined elsewhere...
}

dependencies {
    implementation "com.wultra.android.passphrasemeter:passphrasemeter-core:1.1.0"
}

Note that this documentation is using version 1.0.0 as an example. You can find the latest version in our List of Releases. The Android Studio IDE can also find and offer updates for your application’s dependencies.

To achieve more accurate password testing results, you can add a dependency to additional dictionaries, designed for particular regions:

Additional dependency Region or Language
implementation "com.wultra.android.passphrasemeter:passphrasemeter-dictionary-en:1.1.0" For English speaking people
implementation "com.wultra.android.passphrasemeter:passphrasemeter-dictionary-czsk:1.1.0" For people speaking in Czech or Slovak
implementation "com.wultra.android.passphrasemeter:passphrasemeter-dictionary-ro:1.1.0" For Romanian speaking people

Usage

Before you start using the library, you need to add several imports into your Kotlin source codes:

import com.wultra.android.passphrasemeter.*
import com.wultra.android.passphrasemeter.exceptions.*

Password testing

In order to test the password strength, use following code:

// If your app has an additional dependency on english dictionary,  
// then you need to load that dictionary first.
PasswordTester.getInstance().loadDictionary(assets, "en.dct")
// Test the password
val result = PasswordTester.getInstance().testPassword("test")

You can evaluate any password. The result of such operation is a strength of the password with the following levels:

  • Very Weak
  • Weak
  • Moderate
  • Good
  • Strong

The password testing takes several things into account (keyboard patterns, alphabetical order, repetition, etc…). You can also add a dictionary of well-known words to get rid of passwords that looks strong to algorithms but are actually very common spoken words, or very frequent passwords.

Additional dictionaries

The password strength testing can be improved by loading an appropriate dictionary. Due to limitations in the underlying zxcvbn-c implementation, only one dictionary can be loaded in the memory at the same time. Fortunately, this technical limitation typically doesn’t cause problems in real-world scenarios, because people typically speak in one primary language. So, we decided to prefer fewer changes in the low level “zxcvbn-c” implementation, over more developer-friendly API.

We recommend you to use dictionaries in the following manners:

  1. Determine in which language your user speak
  2. Load an appropriate dictionary with using .loadDictionary() function
  3. Use the password testing functions
  4. Release previously loaded resources:
    PasswordTester.getInstance().freeLoadedDictionary()
    

If you do not free the loaded dictionary, then the allocated resources will be released in the next .loadDictionary() call.

PIN testing

The PIN testing is slightly different to password testing, because the result of such test is a list of findings. Look for this example:

try {
    val passcode = "1456"
    val result = PasswordTester.getInstance().testPin(passcode)
    if (result.issues.isEmpty()) {
        // No issues were found. 
    }
    
    if (result.shouldWarnUserAboutWeakPin()) {
    	// Warn the user that the PIN is weak.
		// Be aware that this property is just a hint based on simple rules. 
		// Consider implementing your own logic based on the `issues` property.
    }
} catch (e: WrongPinException) {
    // PIN format error
}

You can evaluate any PIN. The result of the testing is a collection of issues that were found in PIN. This issues can be:

  • Not Unique - the passcode doesn’t have enough unique digits.
  • Repeating Digits - there is a significant amount of repeating digits in the passcode.
  • Has Pattern - repeating pattern was found in the passcode - 1357 for example.
  • Possibly Date - this passcode can be a date and possibly birthday of the user.
  • Frequently Used - the passcode is in list of most used passcodes.
  • Wrong Input - wrong input - the passcode must contain digits only.

Example project

The repository contains a simple example application, showing usage of the library:

  1. Import Source/examples/Android/PassMeterExample folder in Android Studio
  2. Build and run an example application

If everything works fine, then you can test your passwords in the simulator (or on a real device):

Android Example App

Integration with secure password objects

If your application is using a custom objects, such as Password from PowerAuth mobile SDK for keeping user’s password securely in the memory, then you can easily test PIN or password without a leaking plaintext password in the memory. This is due to fact, that library provide variants of testPin() and testPassword() functions with byte array at input. It’s expected that you provide UTF8 encoded string to both functions to work correctly.

import io.getlime.security.powerauth.core.Password

fun Password.testPin() : PinTestResult {
    var result = PinTestResult(0, emptySet())
    validatePasswordComplexity { 
        result = PasswordTester.getInstance().testPin(it)
        0
    }
    return result
}

fun Password.testPassword(): PasswordStrength {
    var result = PasswordStrength.VERY_WEAK
    validatePasswordComplexity { 
        result = PasswordTester.getInstance().testPassword(it)
        0
    }
    return result
}

Contact

If you need any assistance, do not hesitate to drop us a line at [email protected] or our official wultra.com/discord channel.

Security Disclosure

If you believe you have identified a security vulnerability with Wultra Passphrase Meter, you should report it as soon as possible via email to [email protected]. Please do not post it to a public issue tracker.

Last updated on Dec 11, 2023 (09:36) Edit on Github Send Feedback
Search

develop

Passphrase Meter