SecurerRandomer
Ruby's SecureRandom prefers OpenSSL over other mechanisms (such as
/dev/urandom
and getrandom(2)
). This has recently garnered some
criticism.
RbNaCl provides Ruby bindings to a portable crypto library (libsodium) that includes an alternative, OpenSSL-free pseudo-random number generator (PRNG) implementation.
This gem monkeypatches RbNaCl into SecureRandom and aims to be "bug-for-bug"
compatible with the "stock" implementation of SecureRandom across Ruby
versions. It also provides a nice "do what I mean" random number method that
can be used instead of Kernel.rand
and SecureRandom.random_number
.
History
This gem started out as a very simple monkeypatch to
SecureRandom.random_bytes
and grew as I dug deeper. In newer Rubies, you need
to patch .gen_random
instead of .random_bytes
, and it has no default byte
size.
Generating random numbers proved to be rather tricky due to inconsistencies
between the implementations and functionality of Kernel.rand
and
SecureRandom.random_number
between Ruby versions. For example:
Kernel.rand(nil)
andSecureRandom.random_number(nil)
both return a float such that{ 0.0 <= n < 1.0 }
in Ruby 2.3; butSecureRandom.random_number(nil)
throws an ArgumentError in Ruby 2.2- Kernel
.rand
with an inverted range (e.g.0..-10
) returnsnil
in Ruby 2.2+, but SecureRandom.random_number
throws an ArgumentError in Ruby 2.2 and returns a float such that{ 0.0 <= n < 1.0 }
in Ruby 2.3
Tests started to accumulate so I decided it was probably a good idea to gemify this!
Features
- SecureRandom
.gen_random
(or.random_bytes
)
Monkeypatches SecureRandom such that its various formatter methods (.uuid
,
.hex
, .base64
, .urlsafe_base64
, and .random_bytes
) use RbNaCl for random
byte generation instead of OpenSSL.
- SecureRandom
.random_number
Monkeypatches SecureRandom such that it uses SecurerRandomer.kernel_rand
instead of OpenSSL (or Kernel.rand
) to generate random numbers from numeric
types and ranges. It is bug-for-bug compatible with "stock" SecureRandom,
meaning it "chokes" on the same inputs and throws the same exception types.
- SecurerRandomer
.kernel_rand
A bug-for-bug reimplementation of Kernel.rand
—meaning it "chokes" on
the same inputs and throws the same exception types—that uses RbNaCl as
its source of entropy.
- SecurerRandomer
.rand
An idealistic, "do what I mean" random number method that accepts a variety of
inputs and returns what you might expect. Whereas Kernel.rand(-5.6)
returns
an integer such that { 0 <= n < 5 }
and SecureRandom.random_number(-5.6)
returns a float such that { 0.0 <= n < 1.0 }
, SecurerRandomer.rand(-5.6)
returns a float such that { 0 >= n > -5.6 }
. Whereas Kernel.rand(10..0)
returns nil
and SecureRandom.random_number(10..0)
returns a float such that
{ 0.0 <= n < 1.0 }
(in Ruby 2.3), SecurerRandomer.rand(10..0)
returns an
integer such that { 10 >= n >= 0 }
.
Installation
Please review the installation instructions for RbNaCl. You will need to install either libsodium or rbnacl-libsodium before installing this gem.
Add this line to your application's Gemfile:
gem 'securer_randomer', '~> 0.1.0'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install securer_randomer
Compatibility
SecurerRandomer has been tested under MRI/YARV versions 1.9.3, 2.0, 2.1, 2.2, and 2.3.
DISCLAIMER
Use at your own risk!
I am neither a cryptologist nor a cryptographer. Although I'm fairly confident
in the test suite, serious bugs affecting compatibility, randomness, and
performance may be present. If you're cautious, I would recommend using the
monkeypatched SecureRandom formatter methods for random data and Kernel.rand
for random numbers. Bug reports are welcome.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/mwpastore/securer_randomer.
License
The gem is available as open source under the terms of the MIT License.