The project is in a healthy, maintained state
Validate passwords against configurable policies (length, complexity, common password dictionary, context-aware checks), score strength with entropy-based and zxcvbn-style analysis, detect keyboard patterns and sequences, hash with bcrypt, and generate secure random passwords, passphrases, and PINs.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

philiprehberger-password

Tests Gem Version Last updated

Password strength checking, policy validation, pattern detection, hashing, and secure generation

Requirements

  • Ruby >= 3.1
  • bcrypt gem (optional, for password hashing only)

Installation

Add to your Gemfile:

gem "philiprehberger-password"

Or install directly:

gem install philiprehberger-password

Usage

Strength Scoring

require "philiprehberger/password"

result = Philiprehberger::Password.strength("MyP@ssw0rd!")
result[:score]    # => 3
result[:label]    # => :strong
result[:entropy]  # => 72.08

Common Password Check

Philiprehberger::Password.common?("password")   # => true
Philiprehberger::Password.common?("xK9#mZ2!pQ") # => false

Policy Validation

policy = Philiprehberger::Password::Policy.new(
  min_length: 12,
  require_uppercase: true,
  require_digit: true,
  require_symbol: true,
  reject_common: true,
  custom_passwords: ["companyname", "internalpass"]
)

result = policy.validate("short")
result.valid?  # => false
result.errors  # => ["must be at least 12 characters", ...]
result.score   # => 0

Context-Aware Validation

policy = Philiprehberger::Password::Policy.new

result = policy.validate("johndoe2024!", context: {
  username: "johndoe",
  email: "johndoe@example.com",
  app_name: "myapp"
})
result.valid?  # => false
result.errors  # => ["must not contain your username", "must not contain your email username"]

Keyboard Pattern Detection

patterns = Philiprehberger::Password.keyboard_patterns("qwertyaaa123456")
# => [
#   { type: :keyboard_row, token: "qwerty", start: 0, length: 6, direction: :forward },
#   { type: :repeated, token: "aaa", start: 6, length: 3, repeated_char: "a" },
#   { type: :sequence, token: "123456", start: 9, length: 6, sequence_type: :numeric, direction: :ascending }
# ]

Password Hashing

# Requires bcrypt gem: gem install bcrypt
hash = Philiprehberger::Password.hash("my-secret-password", cost: 12)
# => "$2a$12$..."

Philiprehberger::Password.verify("my-secret-password", hash)
# => true

Philiprehberger::Password.verify("wrong-password", hash)
# => false

Password Generation

# Random password
Philiprehberger::Password.generate(length: 20)
# => "kX9#mZ2!pQ7@wR4bN5&j"

# Passphrase (200+ word list)
Philiprehberger::Password.generate(style: :passphrase, words: 4, separator: "-")
# => "correct-horse-battery-staple"

# PIN
Philiprehberger::Password.generate(style: :pin, length: 6)
# => "482917"

zxcvbn-Style Strength Estimation

result = Philiprehberger::Password.zxcvbn("p@ssw0rd123")
result[:score]              # => 1
result[:crack_time_display] # => "minutes"
result[:patterns]           # => [{ type: :leet, token: "p@ssw0rd", ... }, ...]

API

Philiprehberger::Password

Method Description
.common?(password) Returns true if password is in the common password dictionary
.strength(password) Returns hash with :score (0-4), :label, :entropy
.generate(**options) Generate a password (see options below)
.keyboard_patterns(password) Returns array of detected keyboard/sequence/repeat patterns
.hash(password, cost: 12) Hash password with bcrypt (requires bcrypt gem)
.verify(password, hash) Verify password against bcrypt hash (requires bcrypt gem)
.zxcvbn(password) Returns hash with :score (0-4), :patterns, :crack_time_display

Generate Options

Option Default Description
length 16 Password length
uppercase true Include uppercase letters
lowercase true Include lowercase letters
digits true Include digits
symbols true Include symbols
style nil :passphrase or :pin for alternative styles
words 4 Word count for passphrase style
separator "-" Separator for passphrase style

Philiprehberger::Password::Policy

Method Description
.new(**options) Create policy (min_length, max_length, require_uppercase, require_lowercase, require_digit, require_symbol, reject_common, custom_passwords)
#validate(password, context: {}) Returns Result with .valid?, .errors, .score. Context accepts :username, :email, :app_name

Strength Labels

Score Label Entropy
0 :terrible < 28 bits
1 :weak < 36 bits
2 :fair < 60 bits
3 :strong < 80 bits
4 :excellent >= 80 bits

zxcvbn Pattern Types

Type Description
:dictionary Common password or known word detected
:leet L33t-speak substitution of a known word
:spatial QWERTY keyboard adjacency pattern
:date Date pattern (yyyy, mm/dd/yyyy, etc.)
:sequence Alphabetic or numeric sequence
:repeated Repeated characters

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT