session_keys 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/session_keys.svg)](https://badge.fury.io/rb/session_keys)
|
4
4
|
[![Dependency Status](https://gemnasium.com/badges/github.com/grempe/session-keys-rb.svg)](https://gemnasium.com/github.com/grempe/session-keys-rb)
|
5
5
|
[![Build Status](https://travis-ci.org/grempe/session-keys-rb.svg?branch=master)](https://travis-ci.org/grempe/session-keys-rb)
|
6
6
|
[![Coverage Status](https://coveralls.io/repos/github/grempe/session-keys-rb/badge.svg?branch=master)](https://coveralls.io/github/grempe/session-keys-rb?branch=master)
|
7
7
|
[![Code Climate](https://codeclimate.com/github/grempe/session-keys-rb/badges/gpa.svg)](https://codeclimate.com/github/grempe/session-keys-rb)
|
8
8
|
[![Inline docs](http://inch-ci.org/github/grempe/session-keys-rb.svg?branch=master)](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)�
|