session_keys 0.1.0 → 1.0.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +1 -3
- data/CHANGELOG.md +12 -0
- data/Gemfile +0 -5
- data/README.md +47 -30
- data/RELEASE.md +113 -0
- data/lib/session_keys.rb +65 -127
- data/lib/session_keys/version.rb +1 -1
- data/session_keys.gemspec +8 -19
- metadata +25 -18
- metadata.gz.sig +1 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0173c199f8a44a3f43f5ddb65c1252e30ceeeb6
|
4
|
+
data.tar.gz: 4685fc8e3585592c591ca82e2cbcce91b40c9aa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a169ab65770b8c88d64e3ab03fd7d1060e22233fe036e353b52d35bf993201ddcf508c9040d0c2fb8a68374d6ea3fb14a0f01647cdab1c208928ec591196e2a8
|
7
|
+
data.tar.gz: ddadf6ca0160a531406c98f8b9ca9af1c1b5acf41ba12244e0540f56dd4c8cf77ea6e98f824cc79bc8a41d649d8804eadc74e048987802faca70efacfea2ff72
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## v1.0.0 (9/8/2016)
|
4
|
+
|
5
|
+
- Major refactor and simplification
|
6
|
+
- Compatible with grempe/session-keys-js
|
7
|
+
|
8
|
+
## v0.1.0 (4/30/2016)
|
9
|
+
|
10
|
+
This is the initial ALPHA quality release.
|
11
|
+
|
12
|
+
It is for review only and should not yet be used in production.
|
data/Gemfile
CHANGED
@@ -2,8 +2,3 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in session_keys.gemspec
|
4
4
|
gemspec
|
5
|
-
|
6
|
-
# FIXME : remove when @bascule publishes new rbnacl release
|
7
|
-
# including commit : dc1e8d10b8fc4784130b0864d45b9275a9e979dc
|
8
|
-
# https://github.com/cryptosphere/rbnacl/pull/135
|
9
|
-
gem 'rbnacl', git: 'https://github.com/cryptosphere/rbnacl.git'
|
data/README.md
CHANGED
@@ -1,35 +1,25 @@
|
|
1
|
-
#
|
1
|
+
# sessionKeys (Ruby)
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/session_keys)
|
4
4
|
[](https://gemnasium.com/github.com/grempe/session-keys-rb)
|
5
5
|
[](https://travis-ci.org/grempe/session-keys-rb)
|
6
6
|
[](https://coveralls.io/github/grempe/session-keys-rb?branch=master)
|
7
7
|
[](https://codeclimate.com/github/grempe/session-keys-rb)
|
8
8
|
[](http://inch-ci.org/github/grempe/session-keys-rb)
|
9
9
|
|
10
|
-
|
11
|
-
NaCl compatible [Curve25519](https://cr.yp.to/ecdh.html) encryption and
|
12
|
-
[Ed25519](http://ed25519.cr.yp.to) digital signature keys.
|
10
|
+
`sessionKeys` is a cryptographic tool for the generation of unique user IDs,
|
11
|
+
and NaCl compatible [Curve25519](https://cr.yp.to/ecdh.html) encryption, and
|
12
|
+
[Ed25519](http://ed25519.cr.yp.to) digital signature keys using Ruby.
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
The generated keys are deterministic; for any given ID, password, and
|
19
|
-
strength combination the same keys will always be returned.
|
14
|
+
It is compatible with [grempe/session-keys-js](https://github.com/grempe/session-keys-js)
|
15
|
+
which can generates identical IDs and crypto keys using Javascript when given the
|
16
|
+
same username and passphrase values. Both libraries have extensive tests to
|
17
|
+
ensure they remain interoperable.
|
20
18
|
|
21
|
-
The
|
22
|
-
only the ID parameter your provide and a common salt.
|
19
|
+
The strength of the system lies in the fact that the keypairs are derived from passing an identifier such as a username or email address, and a high-entropy passphrase through the SHA256 cryptographic one-way hash function, and then 'stretching' that username/password into strong key material using the scrypt key derivation function.
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
your password, and a common salt.
|
27
|
-
|
28
|
-
## WARNING : BETA CODE
|
29
|
-
|
30
|
-
This code is new and has not yet been tested in production. Use at your own risk.
|
31
|
-
The interface should be fairly stable now but should not be considered fully
|
32
|
-
stable until v1.0.0 is released.
|
21
|
+
For an overview of the security design, please see the README for the companion
|
22
|
+
project [grempe/session-keys-js](https://github.com/grempe/session-keys-js)
|
33
23
|
|
34
24
|
## Installation
|
35
25
|
|
@@ -51,6 +41,40 @@ Or install it yourself as:
|
|
51
41
|
$ gem install session_keys
|
52
42
|
```
|
53
43
|
|
44
|
+
## Usage
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
SessionKeys.generate('user@example.com', 'my strong passphrase')
|
48
|
+
|
49
|
+
{
|
50
|
+
id: '...',
|
51
|
+
byte_keys: [...],
|
52
|
+
hex_keys: [...],
|
53
|
+
nacl_encryption_key_pairs: [...],
|
54
|
+
nacl_encryption_key_pairs_base64: [...],
|
55
|
+
nacl_signing_key_pairs: [...],
|
56
|
+
nacl_signing_key_pairs_base64: [...],
|
57
|
+
process_time: 250
|
58
|
+
}
|
59
|
+
|
60
|
+
```
|
61
|
+
|
62
|
+
Security Note : Each Array will contain eight values. Since each value at a
|
63
|
+
particular Array index is derived from the same key material it is recommended
|
64
|
+
to choose the different key types you need from different Array indexes. This
|
65
|
+
ensures that each key type was not derived from the same value.
|
66
|
+
|
67
|
+
```
|
68
|
+
# uuid : array index 0
|
69
|
+
output.hex_keys[0]
|
70
|
+
|
71
|
+
# encryption keypair : array index 1
|
72
|
+
output.nacl_encryption_key_pairs[1]
|
73
|
+
|
74
|
+
# signing keypair : array index 2
|
75
|
+
output.nacl_signing_key_pairs[2]
|
76
|
+
```
|
77
|
+
|
54
78
|
### Installation Security : Signed Ruby Gem
|
55
79
|
|
56
80
|
The SessionKeys gem is cryptographically signed. To be sure the gem you install hasn’t
|
@@ -58,7 +82,7 @@ been tampered with you can install it using the following method:
|
|
58
82
|
|
59
83
|
Add required public keys (if you haven’t already) as trusted certificates
|
60
84
|
|
61
|
-
```
|
85
|
+
```
|
62
86
|
# Caveat: Gem certificates are trusted globally, such that adding a
|
63
87
|
# cert.pem for one gem automatically trusts all gems signed by that cert.
|
64
88
|
gem cert --add <(curl -Ls https://raw.githubusercontent.com/cryptosphere/rbnacl/master/bascule.cert)
|
@@ -101,13 +125,6 @@ You can also clone the repository and verify the signatures locally using your
|
|
101
125
|
own GnuPG installation. You can find my certificates and read about how to conduct
|
102
126
|
this verification at [https://www.rempe.us/keys/](https://www.rempe.us/keys/).
|
103
127
|
|
104
|
-
## Usage
|
105
|
-
|
106
|
-
``` ruby
|
107
|
-
keys = SessionKeys.generate('user@example.com', 'my strong passphrase')
|
108
|
-
#=> {...}
|
109
|
-
```
|
110
|
-
|
111
128
|
## Development
|
112
129
|
|
113
130
|
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
data/RELEASE.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# Gem Release Process
|
2
|
+
|
3
|
+
Don't use the `bundle exec rake release` task. It is more convenient,
|
4
|
+
but it skips the process of signing the version release task.
|
5
|
+
|
6
|
+
## Run Tests
|
7
|
+
|
8
|
+
```sh
|
9
|
+
$ bundle exec rake test
|
10
|
+
$ rake wwtd
|
11
|
+
```
|
12
|
+
|
13
|
+
## Git Push
|
14
|
+
|
15
|
+
```sh
|
16
|
+
$ git push
|
17
|
+
```
|
18
|
+
|
19
|
+
Check for regressions in automated tests:
|
20
|
+
|
21
|
+
* [https://travis-ci.org/grempe/session-keys-rb](https://travis-ci.org/grempe/session-keys-rb)
|
22
|
+
* [https://coveralls.io/github/grempe/session-keys-rb?branch=master](https://coveralls.io/github/grempe/session-keys-rb?branch=master)
|
23
|
+
* [https://codeclimate.com/github/grempe/session-keys-rb](https://codeclimate.com/github/grempe/session-keys-rb)
|
24
|
+
* [http://inch-ci.org/github/grempe/session-keys-rb](http://inch-ci.org/github/grempe/session-keys-rb)
|
25
|
+
|
26
|
+
## Bump Version Number and edit CHANGELOG.md
|
27
|
+
|
28
|
+
```sh
|
29
|
+
$ vi lib/session_keys/version.rb
|
30
|
+
$ git add lib/session_keys/version.rb
|
31
|
+
$ vi CHANGELOG.md
|
32
|
+
$ git add CHANGELOG.md
|
33
|
+
```
|
34
|
+
|
35
|
+
## Local Build and Install w/ Signed Gem
|
36
|
+
|
37
|
+
The `build` step should ask for PEM passphrase to sign gem. If it does
|
38
|
+
not ask it means that the signing cert is not present.
|
39
|
+
|
40
|
+
Add certs:
|
41
|
+
|
42
|
+
```sh
|
43
|
+
gem cert --add <(curl -Ls https://raw.github.com/grempe/session-keys-rb/master/certs/gem-public_cert_grempe.pem)
|
44
|
+
gem cert --add <(curl -Ls https://raw.githubusercontent.com/cryptosphere/rbnacl/master/bascule.cert)
|
45
|
+
```
|
46
|
+
|
47
|
+
Build:
|
48
|
+
|
49
|
+
```sh
|
50
|
+
$ rake build
|
51
|
+
Enter PEM pass phrase:
|
52
|
+
session_keys 0.1.0 built to pkg/session_keys-0.1.0.gem.
|
53
|
+
```
|
54
|
+
|
55
|
+
Install locally w/ Cert:
|
56
|
+
|
57
|
+
```sh
|
58
|
+
$ gem uninstall session_keys
|
59
|
+
$ rbenv rehash
|
60
|
+
$ gem install pkg/session_keys-0.1.0.gem -P MediumSecurity
|
61
|
+
Successfully installed session_keys-0.1.0.gem
|
62
|
+
1 gem installed
|
63
|
+
```
|
64
|
+
|
65
|
+
## Git Commit Version and CHANGELOG Changes, Tag and push to Github
|
66
|
+
|
67
|
+
```sh
|
68
|
+
$ git add lib/session_keys/version.rb
|
69
|
+
$ git add CHANGELOG.md
|
70
|
+
$ git commit -m 'Bump version v0.1.1'
|
71
|
+
$ git tag -s v0.1.1 -m "v0.1.1" SHA1_OF_COMMIT
|
72
|
+
```
|
73
|
+
|
74
|
+
Verify last commit and last tag are GPG signed:
|
75
|
+
|
76
|
+
```
|
77
|
+
$ git tag -v v0.1.0
|
78
|
+
...
|
79
|
+
gpg: Good signature from "Glenn Rempe (Code Signing Key) <glenn@rempe.us>" [ultimate]
|
80
|
+
...
|
81
|
+
```
|
82
|
+
|
83
|
+
```
|
84
|
+
$ git log --show-signature
|
85
|
+
...
|
86
|
+
gpg: Good signature from "Glenn Rempe (Code Signing Key) <glenn@rempe.us>" [ultimate]
|
87
|
+
...
|
88
|
+
```
|
89
|
+
|
90
|
+
Push code and tags to GitHub:
|
91
|
+
|
92
|
+
```
|
93
|
+
$ git push
|
94
|
+
$ git push --tags
|
95
|
+
```
|
96
|
+
|
97
|
+
## Push gem to Rubygems.org
|
98
|
+
|
99
|
+
```sh
|
100
|
+
$ gem push pkg/session_keys-0.1.0.gem
|
101
|
+
```
|
102
|
+
|
103
|
+
Verify Gem Push at [https://rubygems.org/gems/session_keys](https://rubygems.org/gems/session_keys)
|
104
|
+
|
105
|
+
## Create a GitHub Release
|
106
|
+
|
107
|
+
Specify the tag we just pushed to attach release to. Copy notes from CHANGELOG.md
|
108
|
+
|
109
|
+
[https://github.com/grempe/session-keys-rb/releases](https://github.com/grempe/session-keys-rb/releases)
|
110
|
+
|
111
|
+
## Announce Release on Twitter
|
112
|
+
|
113
|
+
The normal blah, blah, blah.
|
data/lib/session_keys.rb
CHANGED
@@ -6,75 +6,31 @@ require 'base64'
|
|
6
6
|
|
7
7
|
# SessionKeys deterministic cryptographic key generation.
|
8
8
|
module SessionKeys
|
9
|
-
#
|
10
|
-
|
11
|
-
# compute a key.
|
12
|
-
#
|
13
|
-
# Number of scrypt computations for scrypt to perform for interactive security setting.
|
14
|
-
# Set to SCRYPT_MEMLIMIT_INTERACTIVE / 32
|
15
|
-
#
|
16
|
-
# For interactive, online operations, `SCRYPT_OPSLIMIT_INTERACTIVE` and
|
17
|
-
# `SCRYPT_MEMLIMIT_INTERACTIVE` provide a safe base line for these two parameters.
|
18
|
-
# However, using higher values may improve security.
|
19
|
-
#
|
20
|
-
# See : https://download.libsodium.org/doc/password_hashing/scrypt.html
|
21
|
-
SCRYPT_OPSLIMIT_INTERACTIVE = 2**19
|
22
|
-
|
23
|
-
# Memlimit is the maximum amount of RAM that the function will use, in
|
24
|
-
# bytes. It is highly recommended to allow the function to use at least 16
|
25
|
-
# megabytes.
|
26
|
-
#
|
27
|
-
# Max RAM in Bytes to be used by scrypt for interactive security setting.
|
28
|
-
SCRYPT_MEMLIMIT_INTERACTIVE = 2**24
|
29
|
-
|
30
|
-
# Number of scrypt computations for scrypt to perform for sensitive security setting.
|
31
|
-
# Set to SCRYPT_MEMLIMIT_SENSITIVE / 32
|
32
|
-
#
|
33
|
-
# For highly sensitive data, `SCRYPT_OPSLIMIT_SENSITIVE` and `SCRYPT_MEMLIMIT_SENSITIVE` can
|
34
|
-
# be used as an alternative. But with these parameters, deriving a key takes
|
35
|
-
# about 2 seconds on a 2.8 Ghz Core i7 CPU and requires up to 1 gigabyte of
|
36
|
-
# dedicated RAM.
|
37
|
-
SCRYPT_OPSLIMIT_SENSITIVE = 2**25
|
38
|
-
|
39
|
-
# Max RAM in Bytes to be used by scrypt for sensitive security setting.
|
40
|
-
SCRYPT_MEMLIMIT_SENSITIVE = 2**30
|
41
|
-
|
42
|
-
# Size in Bytes of the scrypt derived output for the id
|
43
|
-
SCRYPT_DIGEST_SIZE_ID = 32
|
44
|
-
|
45
|
-
# Size in Bytes of the scrypt derived output for the password
|
46
|
-
SCRYPT_DIGEST_SIZE_PASSWORD = 256
|
47
|
-
|
48
|
-
# A site-wide 32 Byte common random value that will be concatenated with a value
|
49
|
-
# being hashed for some additional measure of security against dictionary
|
50
|
-
# style attacks. This value was randomly chosen but must be the same across
|
51
|
-
# implementations and is assumed public.
|
52
|
-
PEPPER = 'f01f0a0c44a2d1e7e5b00d7dc78941d404474a90ce7f4ae9d1432bf76fa169e7'.freeze
|
9
|
+
# Size in bytes of the scrypt derived output
|
10
|
+
SCRYPT_DIGEST_SIZE = 256
|
53
11
|
|
54
12
|
# Deterministically generates a collection of derived encryption key material from
|
55
|
-
# a provided id and password. Uses SHA256 and scrypt for key derivation.
|
13
|
+
# a provided id and password/passphrase. Uses SHA256 and scrypt for key derivation.
|
56
14
|
#
|
57
|
-
# @param id [String] a unique UTF-8 String identifier such as a username or
|
15
|
+
# @param id [String] a unique US-ASCII or UTF-8 encoded String identifier such as a username or
|
58
16
|
# email address. Max length 256 characters.
|
59
|
-
# @param password [String] a cryptographically strong UTF-8 password or
|
17
|
+
# @param password [String] a cryptographically strong US-ASCII or UTF-8 encoded password or
|
60
18
|
# passphrase. Max length 256 characters.
|
61
|
-
# @param strength [Symbol] the desired strength of the key derivation. Can be
|
62
|
-
# the symbols :interactive or (:sensitive).
|
63
19
|
# @param min_password_entropy [Integer] the minimum (75) estimated entropy allowed
|
64
20
|
# for the password. This will be measured with Zxcvbn.
|
65
21
|
# @return [Hash] returns a Hash of keys and derived key material.
|
66
22
|
# @raise [ArgumentError] if invalid arguments are provided.
|
67
|
-
def self.generate(id, password,
|
68
|
-
unless id.is_a?(String) &&
|
69
|
-
raise ArgumentError, 'invalid id, not a UTF-8 string'
|
23
|
+
def self.generate(id, password, min_password_entropy = 75)
|
24
|
+
unless id.is_a?(String) && ['US-ASCII', 'UTF-8'].include?(id.encoding.name)
|
25
|
+
raise ArgumentError, 'invalid id, not a US-ASCII or UTF-8 string'
|
70
26
|
end
|
71
27
|
|
72
28
|
unless id.length.between?(1,256)
|
73
29
|
raise ArgumentError, 'invalid id, must be between 1 and 256 characters in length'
|
74
30
|
end
|
75
31
|
|
76
|
-
unless password.is_a?(String) &&
|
77
|
-
raise ArgumentError, 'invalid password, not a UTF-8 string'
|
32
|
+
unless password.is_a?(String) && ['US-ASCII', 'UTF-8'].include?(password.encoding.name)
|
33
|
+
raise ArgumentError, 'invalid password, not a US-ASCII or UTF-8 string'
|
78
34
|
end
|
79
35
|
|
80
36
|
# Enforce max length only due to Zxcvbn taking a *long* time to
|
@@ -92,32 +48,10 @@ module SessionKeys
|
|
92
48
|
raise ArgumentError, "invalid password, must be at least #{min_password_entropy} bits of estimated entropy"
|
93
49
|
end
|
94
50
|
|
95
|
-
unless [:interactive, :sensitive].include?(strength)
|
96
|
-
raise ArgumentError, 'invalid strength, must be :interactive (min), or :sensitive (strong)'
|
97
|
-
end
|
98
|
-
|
99
51
|
start_processing_time = Time.now
|
100
52
|
|
101
|
-
# Run the ID and a 'pepper' (an app common salt) through scrypt. This will be
|
102
|
-
# the system ID for this user. This processing is done to prevent knowledge
|
103
|
-
# of the user on the server side and prevent the ability to reverse this
|
104
|
-
# ID back into a username or email. Using scrypt instead of a SHA256 Hash
|
105
|
-
# is so that it will also take unreasonable effort for someone with a list
|
106
|
-
# of user identifiers from looking up users on the system quickly even if
|
107
|
-
# provided with a local copy of the DB.
|
108
53
|
id_sha256_bytes = RbNaCl::Hash.sha256(id.bytes.pack('C*'))
|
109
|
-
|
110
|
-
id_sha256_pepper_bytes = RbNaCl::Hash.sha256(
|
111
|
-
"#{id}#{id.length}#{PEPPER}#{PEPPER.length}".bytes.pack('C*')
|
112
|
-
)
|
113
|
-
|
114
|
-
id_scrypt_hex = RbNaCl::PasswordHash.scrypt(
|
115
|
-
id_sha256_bytes,
|
116
|
-
id_sha256_pepper_bytes,
|
117
|
-
SCRYPT_OPSLIMIT_INTERACTIVE,
|
118
|
-
SCRYPT_MEMLIMIT_INTERACTIVE,
|
119
|
-
SCRYPT_DIGEST_SIZE_ID
|
120
|
-
).bytes.map { |byte| '%02x' % byte }.join
|
54
|
+
id_sha256_hex = id_sha256_bytes.bytes.map { |byte| '%02x' % byte }.join
|
121
55
|
|
122
56
|
# libsodium : By design, a password whose length is 65 bytes or more is
|
123
57
|
# reduced to SHA-256(password). This can have security implications if the
|
@@ -125,63 +59,67 @@ module SessionKeys
|
|
125
59
|
# SHA-256. Or when upgrading passwords previously hashed with unsalted
|
126
60
|
# SHA-256 to scrypt. If this is a concern, passwords should be pre-hashed
|
127
61
|
# before being hashed using scrypt.
|
128
|
-
|
62
|
+
scrypt_key = RbNaCl::Hash.sha256(password.bytes.pack('C*'))
|
129
63
|
|
130
|
-
|
131
|
-
|
132
|
-
|
64
|
+
# Tie the sycrypt password bytes to the ID they are associate with by
|
65
|
+
# utilizing the ID as the salt. Include the ID length and an additional
|
66
|
+
# string to harden the salt.
|
67
|
+
scrypt_salt = RbNaCl::Hash.sha256([id_sha256_hex,
|
68
|
+
id_sha256_hex.length,
|
69
|
+
'session_keys'].join('').bytes.pack('C*'))
|
133
70
|
|
134
|
-
# Derive
|
135
|
-
# into 32 Byte chunks to serve as deterministic seeds for ID or key
|
136
|
-
# generation. Some derived bytes are reserved for future use.
|
71
|
+
# Derive SCRYPT_DIGEST_SIZE secret bytes
|
137
72
|
password_digest = RbNaCl::PasswordHash.scrypt(
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
73
|
+
scrypt_key,
|
74
|
+
scrypt_salt,
|
75
|
+
16384 * 32,
|
76
|
+
16384 * 32 * 32,
|
77
|
+
SCRYPT_DIGEST_SIZE
|
143
78
|
).bytes
|
144
79
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
80
|
+
num_keys = SCRYPT_DIGEST_SIZE / 32
|
81
|
+
|
82
|
+
byte_keys = []
|
83
|
+
num_keys.times { byte_keys << password_digest.shift(32) }
|
84
|
+
|
85
|
+
hex_keys = byte_keys.map { |key|
|
86
|
+
key.map { |byte| '%02x' % byte }.join
|
87
|
+
}
|
88
|
+
|
89
|
+
nacl_encryption_key_pairs = byte_keys.map { |key|
|
90
|
+
seed = key.pack('C*').force_encoding('ASCII-8BIT')
|
91
|
+
sec_key = RbNaCl::PrivateKey.new(seed)
|
92
|
+
pub_key = sec_key.public_key
|
93
|
+
{secret_key: sec_key, public_key: pub_key}
|
94
|
+
}
|
95
|
+
|
96
|
+
nacl_encryption_key_pairs_base64 = nacl_encryption_key_pairs.map { |keypair|
|
97
|
+
pub_key = Base64.strict_encode64(keypair[:public_key].to_bytes)
|
98
|
+
sec_key = Base64.strict_encode64(keypair[:secret_key].to_bytes)
|
99
|
+
{secret_key: sec_key, public_key: pub_key}
|
100
|
+
}
|
101
|
+
|
102
|
+
nacl_signing_key_pairs = byte_keys.map { |key|
|
103
|
+
seed = key.pack('C*').force_encoding('ASCII-8BIT')
|
104
|
+
sec_key = RbNaCl::SigningKey.new(seed)
|
105
|
+
pub_key = sec_key.verify_key
|
106
|
+
{secret_key: sec_key, public_key: pub_key}
|
107
|
+
}
|
108
|
+
|
109
|
+
nacl_signing_key_pairs_base64 = nacl_signing_key_pairs.map { |keypair|
|
110
|
+
pub_key = Base64.strict_encode64(keypair[:public_key].to_bytes)
|
111
|
+
sec_key = Base64.strict_encode64(keypair[:secret_key].to_bytes)
|
112
|
+
{secret_key: sec_key, public_key: pub_key}
|
113
|
+
}
|
175
114
|
|
176
115
|
{
|
177
|
-
id:
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
nacl_sig_pub_key_b64: Base64.strict_encode64(nacl_sig_pub_key.to_bytes),
|
116
|
+
id: id_sha256_hex,
|
117
|
+
byte_keys: byte_keys,
|
118
|
+
hex_keys: hex_keys,
|
119
|
+
nacl_encryption_key_pairs: nacl_encryption_key_pairs,
|
120
|
+
nacl_encryption_key_pairs_base64: nacl_encryption_key_pairs_base64,
|
121
|
+
nacl_signing_key_pairs: nacl_signing_key_pairs,
|
122
|
+
nacl_signing_key_pairs_base64: nacl_signing_key_pairs_base64,
|
185
123
|
process_time: ((Time.now - start_processing_time)*1000).round(2)
|
186
124
|
}
|
187
125
|
end
|
data/lib/session_keys/version.rb
CHANGED
data/session_keys.gemspec
CHANGED
@@ -18,29 +18,21 @@ Gem::Specification.new do |spec|
|
|
18
18
|
end
|
19
19
|
|
20
20
|
spec.summary = <<-EOF
|
21
|
-
SessionKeys generates
|
21
|
+
SessionKeys generates deterministic user IDs and NaCl encryption/signing
|
22
22
|
keypairs from an identifier, such as a username or email address, a
|
23
23
|
password, and a strength value.
|
24
24
|
EOF
|
25
25
|
|
26
26
|
spec.description = <<-EOF
|
27
27
|
SessionKeys is a cryptographic tool for the deterministic generation of
|
28
|
-
NaCl compatible
|
29
|
-
[Ed25519](http://ed25519.cr.yp.to) digital signature keys.
|
28
|
+
NaCl compatible Curve25519 encryption and Ed25519 digital signature keys.
|
30
29
|
|
31
|
-
The strength of the system
|
30
|
+
The strength of the system is rooted in the fact that the keypairs are derived from
|
32
31
|
passing an identifier, such as a username or email address, and a high-entropy
|
33
|
-
passphrase through the
|
34
|
-
functions. This means that no private key material need ever be
|
35
|
-
The generated keys are deterministic; for any given ID,
|
36
|
-
strength combination the same keys will always be returned.
|
37
|
-
|
38
|
-
The generated ID is passed through `SHA256` and `scrypt` and is derived from
|
39
|
-
only the ID parameter your provide and a common salt.
|
40
|
-
|
41
|
-
The password is also passed through `SHA256` and `scrypt` and NaCl encryption
|
42
|
-
and signing keypairs are derived from the combination of the stretched ID,
|
43
|
-
your password, and a common salt.
|
32
|
+
passphrase through the SHA256 one-way hash and the scrypt key derivation
|
33
|
+
functions. This means that no private key material need ever be writter to
|
34
|
+
disk or transmitted. The generated keys are deterministic; for any given ID,
|
35
|
+
password, and strength combination the same keys will always be returned.
|
44
36
|
EOF
|
45
37
|
|
46
38
|
spec.homepage = 'https://github.com/grempe/session-keys-rb'
|
@@ -51,10 +43,7 @@ Gem::Specification.new do |spec|
|
|
51
43
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
52
44
|
spec.require_paths = ['lib']
|
53
45
|
|
54
|
-
|
55
|
-
# and remove from Gemfile.
|
56
|
-
# https://github.com/cryptosphere/rbnacl/pull/135
|
57
|
-
# spec.add_dependency 'rbnacl', '~> 3.3.0'
|
46
|
+
spec.add_dependency 'rbnacl', '~> 3.4.0'
|
58
47
|
spec.add_dependency 'rbnacl-libsodium', '~> 1.0'
|
59
48
|
spec.add_dependency 'zxcvbn-ruby', '~> 0.1'
|
60
49
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: session_keys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Glenn Rempe
|
@@ -30,8 +30,22 @@ cert_chain:
|
|
30
30
|
zieXiXZSAojfFx9g91fKdIrlPbInHU/BaCxXSLBwvOM0drE+c2ue9X8gB55XAhzX
|
31
31
|
37oBiw==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2016-
|
33
|
+
date: 2016-09-08 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rbnacl
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 3.4.0
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 3.4.0
|
35
49
|
- !ruby/object:Gem::Dependency
|
36
50
|
name: rbnacl-libsodium
|
37
51
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,22 +174,14 @@ dependencies:
|
|
160
174
|
version: '1.3'
|
161
175
|
description: |2
|
162
176
|
SessionKeys is a cryptographic tool for the deterministic generation of
|
163
|
-
NaCl compatible
|
164
|
-
[Ed25519](http://ed25519.cr.yp.to) digital signature keys.
|
177
|
+
NaCl compatible Curve25519 encryption and Ed25519 digital signature keys.
|
165
178
|
|
166
|
-
The strength of the system
|
179
|
+
The strength of the system is rooted in the fact that the keypairs are derived from
|
167
180
|
passing an identifier, such as a username or email address, and a high-entropy
|
168
|
-
passphrase through the
|
169
|
-
functions. This means that no private key material need ever be
|
170
|
-
The generated keys are deterministic; for any given ID,
|
171
|
-
strength combination the same keys will always be returned.
|
172
|
-
|
173
|
-
The generated ID is passed through `SHA256` and `scrypt` and is derived from
|
174
|
-
only the ID parameter your provide and a common salt.
|
175
|
-
|
176
|
-
The password is also passed through `SHA256` and `scrypt` and NaCl encryption
|
177
|
-
and signing keypairs are derived from the combination of the stretched ID,
|
178
|
-
your password, and a common salt.
|
181
|
+
passphrase through the SHA256 one-way hash and the scrypt key derivation
|
182
|
+
functions. This means that no private key material need ever be writter to
|
183
|
+
disk or transmitted. The generated keys are deterministic; for any given ID,
|
184
|
+
password, and strength combination the same keys will always be returned.
|
179
185
|
email:
|
180
186
|
- glenn@rempe.us
|
181
187
|
executables: []
|
@@ -188,10 +194,12 @@ files:
|
|
188
194
|
- ".ruby-version"
|
189
195
|
- ".travis.yml"
|
190
196
|
- ".yardopts"
|
197
|
+
- CHANGELOG.md
|
191
198
|
- CODE_OF_CONDUCT.md
|
192
199
|
- Gemfile
|
193
200
|
- LICENSE.txt
|
194
201
|
- README.md
|
202
|
+
- RELEASE.md
|
195
203
|
- Rakefile
|
196
204
|
- bin/console
|
197
205
|
- bin/setup
|
@@ -222,8 +230,7 @@ rubyforge_project:
|
|
222
230
|
rubygems_version: 2.5.1
|
223
231
|
signing_key:
|
224
232
|
specification_version: 4
|
225
|
-
summary: SessionKeys generates
|
233
|
+
summary: SessionKeys generates deterministic user IDs and NaCl encryption/signing
|
226
234
|
keypairs from an identifier, such as a username or email address, a password, and
|
227
235
|
a strength value.
|
228
236
|
test_files: []
|
229
|
-
has_rdoc:
|
metadata.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
�
|
2
|
-
�gcO����ب�g�f$���È��W˷[���e M���U��cOK��zZj��4ɺ��L�9�|m��85CgE�o�H%��0���~yl�"�I'�>̼���HjX�N�`�/T�D�ۤ��7/�o��Γ��%�H�kӕ���3I���ox��e̟2+��6[��5�q<N�>TW�$^0�;8U�dW�.����k[�E]��v��I��R����8�3B������߹A
|
3
|
-
��Ÿk?
|
1
|
+
S�g{��˟��{��ۂHY���:M���J���UU-�M?ǭ�F��@�W9�� � ���h��x�r}�C����N�Ǚ�6�k3�����֞������y����s��\�$i��]=��,P��������h)�
|