• Stars
    star
    219
  • Rank 181,133 (Top 4 %)
  • Language
    Ruby
  • License
    MIT License
  • Created about 9 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Ruby gem offering bindings for Argon2 password hashing

Ruby Argon2 Gem

This Ruby Gem provides FFI bindings, and a simplified interface, to the Argon2 algorithm. Argon2 is the official winner of the Password Hashing Competition, a several year project to identify a successor to bcrypt/PBKDF/scrypt methods of securely storing passwords. This is an independant project and not official from the PHC team.

Build Status Code Climate Coverage Status

Design

This project has several key tenets to its design:

  • The reference Argon2 implementation is to be used "unaltered". To ensure compliance with this goal, and encourage regular updates from upstream, the upstream library is implemented as a git submodule, and is intended to stay that way.
  • The FFI interface is kept as slim as possible, with wrapper classes preferred to implementing context structs in FFI
  • Security and maintainability take top priority. This can have an impact on platform support. A PR that contains platform specific code paths is unlikely to be accepted.
  • Tested platforms are MRI Ruby 2.7 and 3.0. No assertions are made on other platforms.
  • Errors from the C interface are raised as Exceptions. There are a lot of exception classes, but they tend to relate to things like very broken input, and code bugs. Calls to this library should generally not require a rescue.
  • Test suites should aim for 100% code coverage.
  • Default work values should not be considered constants. I will increase them from time to time.
  • Many Rubocop errors have been disabled, but any commit should avoid new alerts or demonstrate their necessity.

Usage

Require this in your Gemfile like a typical Ruby gem:

require 'argon2'

To generate a hash using specific time and memory cost:

hasher = Argon2::Password.new(t_cost: 2, m_cost: 16, p_cost: 1)
hasher.create("password")
    => "$argon2i$v=19$m=65536,t=2,p=1$jL7lLEAjDN+pY2cG1N8D2g$iwj1ueduCvm6B9YVjBSnAHu+6mKzqGmDW745ALR38Uo"

To utilise default costs:

hasher = Argon2::Password.new
hasher.create("password")

Alternatively, use this shortcut:

Argon2::Password.create("password")
    => "$argon2i$v=19$m=65536,t=2,p=1$61qkSyYNbUgf3kZH3GtHRw$4CQff9AZ0lWd7uF24RKMzqEiGpzhte1Hp8SO7X8bAew"

You can then use this function to verify a password against a given hash. Will return either true or false.

Argon2::Password.verify_password("password", secure_password)

Version 1.2.x will now allow verifying an Argon2id password:

Argon2::Password.verify_password("password", "$argon2id$v=19$m=262144,t=2,p=1$c29tZXNhbHQ$eP4eyR+zqlZX1y5xCFTkw9m5GYx0L5YWwvCFvtlbLow")
  => true

Argon2 supports an optional key value. This should be stored securely on your server, such as alongside your database credentials. Hashes generated with a key will only validate when presented that key.

KEY = "A key"
argon = Argon2::Password.new(t_cost: 2, m_cost: 16, secret: KEY)
myhash = argon.create("A password")
Argon2::Password.verify_password("A password", myhash, KEY)

Ruby 3 Types

I am now shipping signatures in sig/. The following command sets up a testing interface.

RBS_TEST_TARGET="Argon2::*" bundle exec ruby -r rbs/test/setup bin/console

You should also be able to pass Steep checks:

steep check

These tools will need to be installed manually at this time and will be added to Gemfiles after much further testing.

Version 2.0 - Argon 2id

Version 2.x upwards will now default to the Argon2id hash format. This is consistent with current recommendations regarding Argon2 usage. It remains capable of verifying existing hashes.

Important notes regarding version 1.0 upgrade

Version 1.0.0 included a major version bump over 0.1.4 due to several breaking changes. The first of these was an API change, which you can read the background on here.

The second of these is that the reference Argon2 implementation introduced an algorithm change, which produces a hash which is not backwards compatible. This is documented on this PR on the C library. This was a regrettable requirement to address a security concern in the algorithm itself. The two versions of the Argon2 algorithm are numbered 1.0 and 1.3 respectively.

Shortly after this, version 1.0.0 of this gem was released with this breaking change, supporting only Argon2 v1.3. Further time later, the official encoding format was updated, with a spec that included the version number, and the library introduced backward compatibility. This should remove the likelihood of such breaking changes in future.

Platform Issues

The default installation workflow has caused issues with a number of gems under the latest OSX. There is some excellent documentation on the issue and some workarounds in the Jekyll Documentation. With this in mind, OSX is a fully supported OS.

Windows is not. Nobody anywhere has the resources to support Ruby FFI code on Windows.

grsec introduces certain challenges. Please see documentation here.

See the .travis.yml file to see currently tested and supported Ruby versions.

RubyDocs documentation

The usual URL will provide detailed documentation.

FAQ

Don't roll your own crypto!

This gets its own section because someone will raise it. I did not invent or alter this algorithm, or implement it directly. These bindings were written following considerable involvement with the C reference, and a strong focus has been made on following the intent of the algorithm.

It is strongly advised to avoid implementations that utilise off-spec methods of introducing salts, invent imaginary parameters, or which use the word "encryption" in describing the password hashing process

Secure wipe is useless

Although the low level C contains support for "secure memory wipe", any code hitting that layer has copied your password to a dozen places in memory. It should be assumed that such functionality does not exist.

Work maximums may be tighter than reference

The reference implementation is aimed to provide secure hashing for many years. This implementation doesn't want you to DoS yourself in the meantime. Accordingly, some artificial limits exist on work powers. This gem can be much more agile in raising these as technology progresses.

Salts in general

If you are providing your own salt, you are probably using it wrong. The design of any secure hashing system should take care of it for you.

Contributing

Any form of contribution is appreciated, however, please review CONTRIBUTING.md.

Building locally/Tests

To build the gem locally, you will need to run the setup script:

./bin/setup

You can test that the Argon2 C library was properly imported by running the C test suite:

./bin/test

The ruby wrapper test suite includes a property based test. To more strenuously perform this test, you can tune the iterations parameter:

TEST_CHECKS=10000 bundle exec rake test

License

The gem is available as open source under the terms of the MIT License.

More Repositories

1

libscrypt

A shared library that implements scrypt() functionality - a replacement for bcrypt()
C
118
star
2

lol_dht22

A Raspberry Pi DHT22/AM2302 polling application
Shell
81
star
3

maia_mailguard

A fork of maia Mailguard
PHP
50
star
4

reactxss

An XSS smoke test for ReactJS
TypeScript
38
star
5

matasano_challenge

Working through the Matasano Crypto Challenges (cryptopals.com)
Ruby
35
star
6

ct_advisor

A monitoring service for Certificate Transparency
Erlang
32
star
7

open_safety

An application to assist with securing script execution
Rust
29
star
8

3652fa

Office 365 MFA capture toolkit
HTML
12
star
9

erlvulnscan

Concurrent network scanner for CVE-2015-1635
Erlang
10
star
10

azure_enum

Office 365 and Exchange domain federation enumeration tool
Ruby
10
star
11

ssl_manager

Self-hosted service for creating multi-domain SSL certificates
CSS
9
star
12

DisableSMBCompression

CVE-2020-0796 Flaw Mitigation - Active Directory Administrative Templates
8
star
13

messagesodium

Patches ActiveSupport's MessageEncryptor to use libsodium
Ruby
7
star
14

ProxyShellnmap

An nmap script to scan for ProxyShell vulnerable Exchange servers
Lua
6
star
15

IISBackdoorDetect

Detects IIS modules such as IIS-RAID
PowerShell
6
star
16

trackingsadness

GoDaddy's tracking code
JavaScript
5
star
17

vssshield

A Rust project to mitigate Windows ransomware
Rust
5
star
18

mod_randpad

Nginx module that adds a random amount of random data as padding
C
4
star
19

libressl_nginx

Files to create my nginx RPM with libressl
Shell
3
star
20

CVE-2021-34470scanner

A Powrshell script to scan for CVE-2021-34470
PowerShell
2
star
21

pwncheck

Clojure client for Pwned Passwords
Clojure
2
star
22

use_urandom

A Ruby gem that patches SecureRandom to use /dev/urandom
Ruby
2
star
23

ct_advisor_int

Front End Interface for Google Certificate Transparency Monitoring
Ruby
2
star
24

lhnskey

Remote password generator for HP StoreVirtual systems
Shell
2
star
25

wintrayinfo

A Rust based Windows systray app that has BGInfo like capabiities
Rust
2
star
26

p3

Active Directory Password reset web interface
Erlang
1
star
27

SUNBURSTsim

A Powershell script to simulate SUNBURST's evasion techniques
PowerShell
1
star
28

loldns

Fork of djbdns
C
1
star
29

paddingoracle

Ruby framework for exploiting padding oracle vulnerabilities
Ruby
1
star
30

rustypwneddownloader

Rust based pwnedpasswords Downloader
Rust
1
star
31

thaxident

A Gatsby website
JavaScript
1
star
32

fetch_with_checks

TypeScript
1
star
33

lunchcoin

Blockchain application for tracking lunch and coffee orders
Erlang
1
star