rbnacl 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/CHANGES.md +4 -0
- data/README.md +7 -11
- data/lib/rbnacl.rb +4 -0
- data/lib/rbnacl/password_hash.rb +39 -0
- data/lib/rbnacl/password_hash/scrypt.rb +70 -0
- data/lib/rbnacl/rake_tasks.rb +2 -2
- data/lib/rbnacl/test_vectors.rb +11 -0
- data/lib/rbnacl/version.rb +1 -1
- data/spec/rbnacl/password_hash/scrypt_spec.rb +21 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da04c0339f10665de0880687721eb137edb0db2d
|
4
|
+
data.tar.gz: 4f149d92ee6701f70fa6f8715e6132357b6064fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7150574a248de534fa8f141eb891cc3db27a92988e319d55848d21f8323aa0f133416ffc5d4761c62b9d7dcaac7ef0ab70b7df2f45b42d540c857fc852b390a1
|
7
|
+
data.tar.gz: 08f8dfd718c3c75a436a826cc564beacb5533878f7b77d12ea0a057afc1750d421265b0c1172704e98953bece3c893926275aa991f6f86ba7d2d6ca2f85689b1
|
data/.travis.yml
CHANGED
@@ -7,14 +7,13 @@ rvm:
|
|
7
7
|
- ruby-head
|
8
8
|
- jruby
|
9
9
|
- jruby-head
|
10
|
-
- rbx
|
11
|
-
- rbx-head
|
10
|
+
- rbx-2
|
12
11
|
|
13
12
|
matrix:
|
14
13
|
allow_failures:
|
15
14
|
- rvm: ruby-head
|
16
15
|
- rvm: jruby-head
|
17
|
-
- rvm: rbx-
|
16
|
+
- rvm: rbx-2
|
18
17
|
|
19
18
|
notifications:
|
20
19
|
irc: "irc.freenode.org#cryptosphere"
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -67,17 +67,17 @@ reports of successful Windows users.
|
|
67
67
|
|
68
68
|
### libsodium
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
so RbNaCl cannot take advantage of it via FFI. RbNaCl will support usage with
|
73
|
-
the upstream NaCl once it is able to compile a shared library.
|
70
|
+
**NOTE: Want to avoid the hassle of installing libsodium? Use the
|
71
|
+
[rbnacl-libsodium](https://github.com/cryptosphere/rbnacl-libsodium) gem**
|
74
72
|
|
75
|
-
|
76
|
-
of NaCl based upon the reference C code. Please see the libsodium project
|
77
|
-
for information regarding installation:
|
73
|
+
To use RbNaCl, you will need to install libsodium:
|
78
74
|
|
79
75
|
https://github.com/jedisct1/libsodium
|
80
76
|
|
77
|
+
For OS X users, libsodium is available via homebrew and can be installed with:
|
78
|
+
|
79
|
+
brew install libsodium
|
80
|
+
|
81
81
|
For FreeBSD users, libsodium is available both via pkgng and ports. To install
|
82
82
|
a binary package:
|
83
83
|
|
@@ -88,10 +88,6 @@ portmaster or portupgrade), or use make as follows:
|
|
88
88
|
|
89
89
|
cd /usr/ports/security/libsodium; make install clean
|
90
90
|
|
91
|
-
For OS X users, libsodium is available via homebrew and can be installed with:
|
92
|
-
|
93
|
-
brew install libsodium
|
94
|
-
|
95
91
|
### RbNaCl gem
|
96
92
|
|
97
93
|
Once you have libsodium installed, add this line to your application's Gemfile:
|
data/lib/rbnacl.rb
CHANGED
@@ -63,6 +63,10 @@ module RbNaCl
|
|
63
63
|
require "rbnacl/hash/sha512"
|
64
64
|
require "rbnacl/hash/blake2b"
|
65
65
|
|
66
|
+
# Password hash function: scrypt
|
67
|
+
require "rbnacl/password_hash"
|
68
|
+
require "rbnacl/password_hash/scrypt"
|
69
|
+
|
66
70
|
# HMAC: SHA256 and SHA512256
|
67
71
|
require "rbnacl/hmac/sha256"
|
68
72
|
require "rbnacl/hmac/sha512256"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
# Password hashing functions
|
4
|
+
#
|
5
|
+
# These hash functions are designed specifically for the purposes of securely
|
6
|
+
# storing passwords in a way that they can be checked against a supplied
|
7
|
+
# password but an attacker who obtains a hash cannot easily reverse them back
|
8
|
+
# into the original password.
|
9
|
+
#
|
10
|
+
# Unlike normal hash functions, which are intentionally designed to hash data
|
11
|
+
# as quickly as they can while remaining secure, password hashing functions
|
12
|
+
# are intentionally designed to be slow so they are hard for attackers to
|
13
|
+
# brute force.
|
14
|
+
#
|
15
|
+
# All password hashing functions take a "salt" value which should be randomly
|
16
|
+
# generated on a per-password basis (using RbNaCl::Random, accept no
|
17
|
+
# subsitutes)
|
18
|
+
#
|
19
|
+
# All of them also take a CPU work factor, which increases the amount of
|
20
|
+
# computation needed to produce the digest.
|
21
|
+
module PasswordHash
|
22
|
+
# scrypt: the original sequential memory hard password hashing function.
|
23
|
+
# This is also the only password hashing function supported by libsodium,
|
24
|
+
# but that's okay, because it's pretty awesome.
|
25
|
+
#
|
26
|
+
# @param [String] password to be hashed
|
27
|
+
# @param [String] salt to make the digest unique
|
28
|
+
# @param [Integer] opslimit the CPU cost (e.g. 2**20)
|
29
|
+
# @param [Integer] memlimit the memory cost (e.g. 2**24)
|
30
|
+
# @param [Integer] digest_size of the output
|
31
|
+
#
|
32
|
+
# @raise [CryptoError] If calculating the digest fails for some reason.
|
33
|
+
#
|
34
|
+
# @return [String] The scrypt digest as raw bytes
|
35
|
+
def self.scrypt(password, salt, opslimit, memlimit, digest_size = 64)
|
36
|
+
SCrypt.new(opslimit, memlimit, digest_size).digest(password, salt)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
module RbNaCl
|
3
|
+
module PasswordHash
|
4
|
+
# The scrypt sequential memory hard password hashing function
|
5
|
+
#
|
6
|
+
# scrypt is a password hash (or password based KDF). That is to say, where
|
7
|
+
# most hash functions are designed to be fast because hashing is often a
|
8
|
+
# bottleneck, scrypt is slow by design, because it's trying to "strengthen"
|
9
|
+
# the password by combining it with a random "salt" value then perform a
|
10
|
+
# series of operation on the result which are slow enough to defeat
|
11
|
+
# brute-force password cracking attempts.
|
12
|
+
#
|
13
|
+
# scrypt is similar to the bcrypt and pbkdf2 password hashes in that it's
|
14
|
+
# designed to strengthen passwords, but includes a new design element
|
15
|
+
# called "sequential memory hardness" which helps defeat attempts by
|
16
|
+
# attackers to compensate for their lack of memory (since they're typically
|
17
|
+
# on GPUs or FPGAs) with additional computation.
|
18
|
+
class SCrypt
|
19
|
+
extend Sodium
|
20
|
+
|
21
|
+
begin
|
22
|
+
sodium_type :pwhash
|
23
|
+
sodium_primitive :scryptxsalsa208sha256
|
24
|
+
|
25
|
+
sodium_constant :SALTBYTES
|
26
|
+
|
27
|
+
sodium_function :scrypt,
|
28
|
+
:crypto_pwhash_scryptxsalsa208sha256,
|
29
|
+
[:pointer, :ulong_long, :pointer, :ulong_long, :pointer, :ulong_long, :size_t]
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# Create a new SCrypt password hash object
|
34
|
+
#
|
35
|
+
# @param [Integer] opslimit the CPU cost (e.g. 2**20)
|
36
|
+
# @param [Integer] memlimit the memory cost (e.g. 2**24)
|
37
|
+
#
|
38
|
+
# @return [RbNaCl::PasswordHash::SCrypt] An SCrypt password hasher object
|
39
|
+
def initialize(opslimit, memlimit, digest_size = 64)
|
40
|
+
# TODO: sanity check these parameters
|
41
|
+
@opslimit, @memlimit = opslimit, memlimit
|
42
|
+
|
43
|
+
# TODO: check digest size validity
|
44
|
+
#raise LengthError, "digest size too short" if @digest_size < BYTES_MIN
|
45
|
+
#raise LengthError, "digest size too long" if @digest_size > BYTES_MAX
|
46
|
+
|
47
|
+
@digest_size = digest_size
|
48
|
+
end
|
49
|
+
|
50
|
+
# Calculate an scrypt digest for a given password and salt
|
51
|
+
#
|
52
|
+
# @param [String] password to be hashed
|
53
|
+
# @param [String] salt to make the digest unique
|
54
|
+
#
|
55
|
+
# @return [String] scrypt digest of the string as raw bytes
|
56
|
+
def digest(password, salt)
|
57
|
+
digest = Util.zeros(@digest_size)
|
58
|
+
salt = Util.check_string(salt, SALTBYTES, "salt")
|
59
|
+
|
60
|
+
self.class.scrypt(digest, @digest_size, password, password.bytesize, salt, @opslimit, @memlimit) || raise(CryptoError, "scrypt failed!")
|
61
|
+
digest
|
62
|
+
end
|
63
|
+
rescue FFI::NotFoundError
|
64
|
+
def initialize(opslimit, memlimit, digest_size = 64)
|
65
|
+
raise NotImplementedError, "scrypt not implemented in this version of libsodium"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/rbnacl/rake_tasks.rb
CHANGED
@@ -3,8 +3,8 @@ require 'rake'
|
|
3
3
|
require 'rake/clean'
|
4
4
|
require 'digest/sha2'
|
5
5
|
|
6
|
-
LIBSODIUM_VERSION = "0.
|
7
|
-
LIBSODIUM_DIGEST = "
|
6
|
+
LIBSODIUM_VERSION = "0.5.0"
|
7
|
+
LIBSODIUM_DIGEST = "3ca0a0619199a2adb3449eb7f1bf6e1f4fb2ef8514da9133f7f043b8b5cdf9f0"
|
8
8
|
|
9
9
|
def sh_hidden(command)
|
10
10
|
STDERR.puts("*** Executing: #{command}")
|
data/lib/rbnacl/test_vectors.rb
CHANGED
@@ -85,6 +85,17 @@ module RbNaCl
|
|
85
85
|
:blake2b_keyed_digest => "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e9248" +
|
86
86
|
"4be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
|
87
87
|
|
88
|
+
# scrypt test vectors
|
89
|
+
# Taken from http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#page-14
|
90
|
+
:scrypt_password => "4a857e2ee8aa9b6056f2424e84d24a72473378906ee04a46cb05311502d5250b" +
|
91
|
+
"82ad86b83c8f20a23dbb74f6da60b0b6ecffd67134d45946ac8ebfb3064294bc" +
|
92
|
+
"097d43ced68642bfb8bbbdd0f50b30118f5e",
|
93
|
+
:scrypt_salt => "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258",
|
94
|
+
:scrypt_opslimit => 758010,
|
95
|
+
:scrypt_memlimit => 5432947,
|
96
|
+
:scrypt_digest => "bcc5c2fd785e4781d1201ed43d84925537e2a540d3de55f5812f29e9dd0a4a00" +
|
97
|
+
"451a5c8ddbb4862c03d45c75bf91b7fb49265feb667ad5c899fdbf2ca19eac67",
|
98
|
+
|
88
99
|
# Auth test vectors
|
89
100
|
# Taken from NaCl distribution
|
90
101
|
#
|
data/lib/rbnacl/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe RbNaCl::PasswordHash::SCrypt do
|
5
|
+
let(:reference_password) { vector :scrypt_password }
|
6
|
+
let(:reference_salt) { vector :scrypt_salt }
|
7
|
+
let(:reference_opslimit) { RbNaCl::TestVectors[:scrypt_opslimit] }
|
8
|
+
let(:reference_memlimit) { RbNaCl::TestVectors[:scrypt_memlimit] }
|
9
|
+
let(:reference_digest) { vector :scrypt_digest }
|
10
|
+
|
11
|
+
it "calculates the correct diest for a reference password/salt" do
|
12
|
+
digest = RbNaCl::PasswordHash.scrypt(
|
13
|
+
reference_password,
|
14
|
+
reference_salt,
|
15
|
+
reference_opslimit,
|
16
|
+
reference_memlimit
|
17
|
+
)
|
18
|
+
|
19
|
+
expect(digest).to eq reference_digest
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbnacl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain:
|
12
12
|
- bascule.cert
|
13
|
-
date: 2014-05-
|
13
|
+
date: 2014-05-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ffi
|
@@ -108,6 +108,8 @@ files:
|
|
108
108
|
- lib/rbnacl/init.rb
|
109
109
|
- lib/rbnacl/key_comparator.rb
|
110
110
|
- lib/rbnacl/one_time_auths/poly1305.rb
|
111
|
+
- lib/rbnacl/password_hash.rb
|
112
|
+
- lib/rbnacl/password_hash/scrypt.rb
|
111
113
|
- lib/rbnacl/rake_tasks.rb
|
112
114
|
- lib/rbnacl/random.rb
|
113
115
|
- lib/rbnacl/secret_boxes/xsalsa20poly1305.rb
|
@@ -132,6 +134,7 @@ files:
|
|
132
134
|
- spec/rbnacl/hash_spec.rb
|
133
135
|
- spec/rbnacl/hmac/sha256_spec.rb
|
134
136
|
- spec/rbnacl/hmac/sha512256_spec.rb
|
137
|
+
- spec/rbnacl/password_hash/scrypt_spec.rb
|
135
138
|
- spec/rbnacl/random_spec.rb
|
136
139
|
- spec/rbnacl/secret_box_spec.rb
|
137
140
|
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|
@@ -181,6 +184,7 @@ test_files:
|
|
181
184
|
- spec/rbnacl/hash_spec.rb
|
182
185
|
- spec/rbnacl/hmac/sha256_spec.rb
|
183
186
|
- spec/rbnacl/hmac/sha512256_spec.rb
|
187
|
+
- spec/rbnacl/password_hash/scrypt_spec.rb
|
184
188
|
- spec/rbnacl/random_spec.rb
|
185
189
|
- spec/rbnacl/secret_box_spec.rb
|
186
190
|
- spec/rbnacl/signatures/ed25519/signing_key_spec.rb
|