Project

xcrypt

0.0
No release in over 3 years
Ruby FFI bindings for libxcrypt, a modern library for one-way hashing of passwords. Supports yescrypt, bcrypt, SHA-512, SHA-256, and other algorithms provided by the bundled libxcrypt source (ext/libxcrypt).
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

Runtime

~> 1.0
~> 13.0
 Project Readme

xcrypt

Ruby FFI bindings for libxcrypt, a modern library for one-way password hashing. Supports yescrypt, bcrypt, SHA-512, SHA-256, and other algorithms. The library is bundled as a submodule and compiled statically into the extension, so no system installation of libxcrypt is required.

Installation

Add this line to your Gemfile:

gem "xcrypt"

Then run:

bundle install

Usage

Hashing a password

Call XCrypt.crypt with a passphrase and an algorithm. The library picks a fresh random salt automatically.

hash = XCrypt.yescrypt("hunter2")
# => "$y$j9T$..."

Verifying a password

XCrypt.verify("hunter2", hash)  # => true
XCrypt.verify("wrong",   hash)  # => false

verify returns false for nil, empty strings, and strings starting with * (libxcrypt error markers). It never raises.

Generating a setting string manually

A setting string encodes the algorithm prefix and salt. You can generate one yourself and pass it to crypt directly:

setting = XCrypt.generate_setting(:bcrypt)
hash    = XCrypt.crypt("hunter2", setting)

Passing an explicit setting is useful when you need to control the cost factor:

setting = XCrypt.generate_setting(:sha512, cost: 10_000)
hash    = XCrypt.crypt("hunter2", setting)

Note that you should always generate a new setting for each password, as it contains a random salt. Reusing the same setting for multiple passwords is not recommended.

Detecting the algorithm of a stored hash

XCrypt.detect_algorithm("$6$rounds=5000$abc$...")  # => :sha512
XCrypt.detect_algorithm("$2b$12$...")              # => :bcrypt

Listing supported algorithms

XCrypt.algorithms
# => [:yescrypt, :gost_yescrypt, :scrypt, :bcrypt, :sha512, :sha256, :sha1, :sun_md5, :md5, :bsdi_des, :des]

Algorithms

Symbol Prefix Notes
:yescrypt $y$ Recommended for new deployments
:gost_yescrypt $gy$ yescrypt with GOST hash
:scrypt $7$ Memory-hard
:bcrypt $2b$ Widely deployed, 72-byte passphrase limit
:sha512 $6$
:sha256 $5$
:sha1 $sha1$ Legacy
:sun_md5 $md5 Legacy
:md5 $1$ Legacy
:bsdi_des _ Legacy
:des (none) Legacy, 8-character passphrase limit

For new deployments, use :yescrypt or :bcrypt. The legacy algorithms are provided for verifying existing hashes only.

Error handling

XCrypt.crypt and XCrypt.generate_setting raise XCrypt::Error on failure (invalid setting, unsupported algorithm, bad cost value). XCrypt.verify catches these internally and returns false instead.

XCrypt.crypt("password", "!!!invalid!!!")
# => raises XCrypt::Error

XCrypt.generate_setting(:nonexistent)
# => raises ArgumentError

Development

bundle install
bundle exec rake compile   # build the native extension
bundle exec rake test      # run the test suite
bundle exec rake           # compile + test

License

MIT. See MIT-LICENSE.

The bundled libxcrypt library is licensed under LGPL-2.1. See ext/libxcrypt/COPYING.LIB.