session_keys 0.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.
@@ -0,0 +1 @@
1
+ 2.3.1
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.2.4
5
+ - 2.3.1
6
+ - jruby-9.0.5.0
7
+ before_install: gem install bundler -v 1.12.1
@@ -0,0 +1 @@
1
+ --no-private lib/**/*.rb - README.md LICENSE.txt CODE_OF_CONDUCT.md
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at glenn@rempe.us. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in session_keys.gemspec
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'
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Glenn Rempe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,145 @@
1
+ # SessionKeys
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/session-keys-rb.svg)](https://badge.fury.io/rb/session-keys-rb)
4
+ [![Dependency Status](https://gemnasium.com/badges/github.com/grempe/session-keys-rb.svg)](https://gemnasium.com/github.com/grempe/session-keys-rb)
5
+ [![Build Status](https://travis-ci.org/grempe/session-keys-rb.svg?branch=master)](https://travis-ci.org/grempe/session-keys-rb)
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
+ [![Code Climate](https://codeclimate.com/github/grempe/session-keys-rb/badges/gpa.svg)](https://codeclimate.com/github/grempe/session-keys-rb)
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
+
10
+ SessionKeys is a cryptographic tool for the deterministic generation of
11
+ NaCl compatible [Curve25519](https://cr.yp.to/ecdh.html) encryption and
12
+ [Ed25519](http://ed25519.cr.yp.to) digital signature keys.
13
+
14
+ The strength of the system lies in the fact that the keypairs are derived from
15
+ passing an identifier, such as a username or email address, and a high-entropy
16
+ passphrase through the `SHA256` hash and the `scrypt` key derivation
17
+ functions. This means that no private key material need ever be stored to disk.
18
+ The generated keys are deterministic; for any given ID, password, and
19
+ strength combination the same keys will always be returned.
20
+
21
+ The generated ID is passed through `SHA256` and `scrypt` and is derived from
22
+ only the ID parameter your provide and a common salt.
23
+
24
+ The password is also passed through `SHA256` and `scrypt` and NaCl encryption
25
+ and signing keypairs are derived from the combination of the stretched ID,
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.
33
+
34
+ ## Installation
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ``` ruby
39
+ gem 'session_keys'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ ``` text
45
+ $ bundle
46
+ ```
47
+
48
+ Or install it yourself as:
49
+
50
+ ``` text
51
+ $ gem install session_keys
52
+ ```
53
+
54
+ ### Installation Security : Signed Ruby Gem
55
+
56
+ The SessionKeys gem is cryptographically signed. To be sure the gem you install hasn’t
57
+ been tampered with you can install it using the following method:
58
+
59
+ Add required public keys (if you haven’t already) as trusted certificates
60
+
61
+ ``` text
62
+ # Caveat: Gem certificates are trusted globally, such that adding a
63
+ # cert.pem for one gem automatically trusts all gems signed by that cert.
64
+ gem cert --add <(curl -Ls https://raw.githubusercontent.com/cryptosphere/rbnacl/master/bascule.cert)
65
+ gem cert --add <(curl -Ls https://raw.github.com/grempe/session-keys-rb/master/certs/gem-public_cert_grempe.pem)
66
+ ```
67
+
68
+ To install, it is possible to specify either `HighSecurity` or `MediumSecurity`
69
+ mode. Since the `session_keys` gem depends on one or more gems that are not cryptographically
70
+ signed you will likely need to use `MediumSecurity`. You should receive a warning
71
+ if any signed gem does not match its signature.
72
+
73
+ ``` text
74
+ # All dependent gems must be signed and verified.
75
+ gem install session_keys -P HighSecurity
76
+ ```
77
+
78
+ ``` text
79
+ # All signed dependent gems must be verified.
80
+ gem install session_keys -P MediumSecurity
81
+ ```
82
+
83
+ ``` text
84
+ # Same as above, except Bundler only recognizes
85
+ # the long --trust-policy flag, not the short -P
86
+ bundle --trust-policy MediumSecurity
87
+ ```
88
+
89
+ You can [learn more about security and signed Ruby Gems](http://guides.rubygems.org/security/).
90
+
91
+ ### Installation Security : Signed Git Commits
92
+
93
+ Most, if not all, of the commits and tags to the repository for this code are
94
+ signed with my PGP/GPG code signing key. I have uploaded my code signing public
95
+ keys to GitHub and you can now verify those signatures with the GitHub UI.
96
+ See [this list of commits](https://github.com/grempe/session-keys-rb/commits/master)
97
+ and look for the `Verified` tag next to each commit. You can click on that tag
98
+ for additional information.
99
+
100
+ You can also clone the repository and verify the signatures locally using your
101
+ own GnuPG installation. You can find my certificates and read about how to conduct
102
+ this verification at [https://www.rempe.us/keys/](https://www.rempe.us/keys/).
103
+
104
+ ## Usage
105
+
106
+ ``` ruby
107
+ keys = SessionKeys.generate('user@example.com', 'my strong passphrase')
108
+ #=> {...}
109
+ ```
110
+
111
+ ## Development
112
+
113
+ After checking out the repo, run `bin/setup` to install dependencies. Then,
114
+ run `rake test` to run the tests. You can also run `bin/console` for an
115
+ interactive prompt that will allow you to experiment.
116
+
117
+ To install this gem onto your local machine, run `bundle exec rake install`.
118
+
119
+ ## Contributing
120
+
121
+ Bug reports and pull requests are welcome on GitHub at
122
+ [https://github.com/grempe/session-keys-rb](https://github.com/grempe/session-keys-rb).
123
+ This project is intended to be a safe, welcoming space for collaboration, and
124
+ contributors are expected to adhere to the
125
+ [Contributor Covenant](http://contributor-covenant.org) code of conduct.
126
+
127
+ ## Legal
128
+
129
+ ### Copyright
130
+
131
+ (c) 2016 Glenn Rempe <[glenn@rempe.us](mailto:glenn@rempe.us)> ([https://www.rempe.us/](https://www.rempe.us/))
132
+
133
+ ### License
134
+
135
+ The gem is available as open source under the terms of
136
+ the [MIT License](http://opensource.org/licenses/MIT).
137
+
138
+ ### Warranty
139
+
140
+ Unless required by applicable law or agreed to in writing,
141
+ software distributed under the License is distributed on an
142
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
143
+ either express or implied. See the LICENSE.txt file for the
144
+ specific language governing permissions and limitations under
145
+ the License.
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'wwtd/tasks'
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'test'
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/**/*_test.rb']
9
+ t.verbose = false
10
+ t.warning = false
11
+ end
12
+
13
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'session_keys'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require 'pry'
11
+ Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDYDCCAkigAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQ4wDAYDVQQDDAVnbGVu
3
+ bjEVMBMGCgmSJomT8ixkARkWBXJlbXBlMRIwEAYKCZImiZPyLGQBGRYCdXMwHhcN
4
+ MTYwNDExMDI0NTU0WhcNMTcwNDExMDI0NTU0WjA7MQ4wDAYDVQQDDAVnbGVubjEV
5
+ MBMGCgmSJomT8ixkARkWBXJlbXBlMRIwEAYKCZImiZPyLGQBGRYCdXMwggEiMA0G
6
+ CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZqTH5Jf+D/W2B4BIiL49CpHa86rK/
7
+ oT+v3xZwuEE92lJea+ygn3IAsidVTW47AKE6Lt3UqUkGQGKxsqH/Dhir08BqjLlD
8
+ gBUozGZpM3B6uWZnD6QXLbOmZeGVDnwB/QDfzaawN1i3smlYxYT+KNLjl80aN3we
9
+ /cHAWG7JG47AF/S91mYcg1WgZnDgZt9+RyVR1AsfYbM+SidOSoXEOHPCbuUxLKJb
10
+ gj5ieCFhm5GNWEugvgiX/ruas+VHV0fF3fzjYlU2fZPTuQyB4UD5FWX4UqdsBf3w
11
+ jB94TDBsJ3FVGPbggEhLGKd8pbQmBIOqXolGaqhs7dnuf5imu5mAXHC1AgMBAAGj
12
+ bzBtMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRfxEyosUbKjfFa
13
+ j+gae2CcT3aFCTAZBgNVHREEEjAQgQ5nbGVubkByZW1wZS51czAZBgNVHRIEEjAQ
14
+ gQ5nbGVubkByZW1wZS51czANBgkqhkiG9w0BAQUFAAOCAQEAzgK20+MNOknR9Kx6
15
+ RisI3DsioCADjGldxY+INrwoTfPDVmNm4GdTYC+V+/BvxJw1RqHjEbuXSg0iibQC
16
+ 4vN+th0Km7dnas/td1i+EKfGencfyQyecIaG9l3kbCkCWnldRtZ+BS5EfP2ML2u8
17
+ fyCtze/Piovu8IwXL1W5kGZMnvzLmWxdqI3VPUou40n8F+EiMMLgd53kpzjtNOau
18
+ 4W+mqVGOwlEGVSgI5+0SIsD8pvc62PlPWTv0kn1bcufKKCZmoVmpfbe3j4JpBInq
19
+ zieXiXZSAojfFx9g91fKdIrlPbInHU/BaCxXSLBwvOM0drE+c2ue9X8gB55XAhzX
20
+ 37oBiw==
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,188 @@
1
+ require 'session_keys/version'
2
+ require 'rbnacl/libsodium'
3
+ require 'rbnacl'
4
+ require 'zxcvbn'
5
+ require 'base64'
6
+
7
+ # SessionKeys deterministic cryptographic key generation.
8
+ module SessionKeys
9
+ # Opslimit represents a maximum amount of computations to perform.
10
+ # Raising this number will make the function require more CPU cycles to
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
53
+
54
+ # Deterministically generates a collection of derived encryption key material from
55
+ # a provided id and password. Uses SHA256 and scrypt for key derivation.
56
+ #
57
+ # @param id [String] a unique UTF-8 String identifier such as a username or
58
+ # email address. Max length 256 characters.
59
+ # @param password [String] a cryptographically strong UTF-8 password or
60
+ # 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
+ # @param min_password_entropy [Integer] the minimum (75) estimated entropy allowed
64
+ # for the password. This will be measured with Zxcvbn.
65
+ # @return [Hash] returns a Hash of keys and derived key material.
66
+ # @raise [ArgumentError] if invalid arguments are provided.
67
+ def self.generate(id, password, strength = :sensitive, min_password_entropy = 75)
68
+ unless id.is_a?(String) && id.encoding.name == 'UTF-8'
69
+ raise ArgumentError, 'invalid id, not a UTF-8 string'
70
+ end
71
+
72
+ unless id.length.between?(1,256)
73
+ raise ArgumentError, 'invalid id, must be between 1 and 256 characters in length'
74
+ end
75
+
76
+ unless password.is_a?(String) && password.encoding.name == 'UTF-8'
77
+ raise ArgumentError, 'invalid password, not a UTF-8 string'
78
+ end
79
+
80
+ # Enforce max length only due to Zxcvbn taking a *long* time to
81
+ # process long strings and determine entropy.
82
+ unless password.length.between?(1,256)
83
+ raise ArgumentError, 'invalid password, must be between 1 and 256 characters in length'
84
+ end
85
+
86
+ unless min_password_entropy.is_a?(Integer) && min_password_entropy.between?(1, 512)
87
+ raise ArgumentError, 'invalid min_password_entropy, must be an Integer between 1 and 512'
88
+ end
89
+
90
+ password_test = Zxcvbn.test(password)
91
+ unless password_test.entropy.round >= min_password_entropy
92
+ raise ArgumentError, "invalid password, must be at least #{min_password_entropy} bits of estimated entropy"
93
+ end
94
+
95
+ unless [:interactive, :sensitive].include?(strength)
96
+ raise ArgumentError, 'invalid strength, must be :interactive (min), or :sensitive (strong)'
97
+ end
98
+
99
+ start_processing_time = Time.now
100
+
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
+ 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
121
+
122
+ # libsodium : By design, a password whose length is 65 bytes or more is
123
+ # reduced to SHA-256(password). This can have security implications if the
124
+ # password is present in another password database using raw, unsalted
125
+ # SHA-256. Or when upgrading passwords previously hashed with unsalted
126
+ # SHA-256 to scrypt. If this is a concern, passwords should be pre-hashed
127
+ # before being hashed using scrypt.
128
+ password_sha256_bytes = RbNaCl::Hash.sha256(password.bytes.pack('C*'))
129
+
130
+ password_sha256_pepper_bytes = RbNaCl::Hash.sha256(
131
+ "#{id_scrypt_hex}#{id_scrypt_hex.length}#{PEPPER}#{PEPPER.length}".bytes.pack('C*')
132
+ )
133
+
134
+ # Derive SCRYPT_DIGEST_SIZE_PASSWORD secret bytes. They will be split
135
+ # into 32 Byte chunks to serve as deterministic seeds for ID or key
136
+ # generation. Some derived bytes are reserved for future use.
137
+ password_digest = RbNaCl::PasswordHash.scrypt(
138
+ password_sha256_bytes,
139
+ password_sha256_pepper_bytes,
140
+ strength == :interactive ? SCRYPT_OPSLIMIT_INTERACTIVE : SCRYPT_OPSLIMIT_SENSITIVE,
141
+ strength == :interactive ? SCRYPT_MEMLIMIT_INTERACTIVE : SCRYPT_MEMLIMIT_SENSITIVE,
142
+ SCRYPT_DIGEST_SIZE_PASSWORD
143
+ ).bytes
144
+
145
+ # Break up the scrypt digest into 32 Byte seeds.
146
+ secret_bytes = []
147
+ (SCRYPT_DIGEST_SIZE_PASSWORD/32).times { secret_bytes << password_digest.shift(32) }
148
+
149
+ # Seed 0 : RbNaCl::SimpleBox
150
+ # The seed bytes are used as a 32 Byte key suitable for
151
+ # simple symetric key encryption using `RbNaCl::SimpleBox`. SimpleBox is
152
+ # a wrapper around NaCl SecretBox construct with automated nonce management.
153
+ #
154
+ # To encrypt/decreypt with this object try:
155
+ # ciphertext = nacl_simple_box.encrypt('foobar')
156
+ # plaintext = nacl_simple_box.decrypt(ciphertext)
157
+ nacl_simple_box_key = secret_bytes[0].pack('C*').force_encoding('ASCII-8BIT')
158
+ nacl_simple_box = RbNaCl::SimpleBox.from_secret_key(nacl_simple_box_key)
159
+
160
+ # Seed 1 : NaCl Box Keypair
161
+ nacl_enc_sec_seed = secret_bytes[1].pack('C*').force_encoding('ASCII-8BIT')
162
+ nacl_enc_sec_key = RbNaCl::PrivateKey.new(nacl_enc_sec_seed)
163
+ nacl_enc_pub_key = nacl_enc_sec_key.public_key
164
+
165
+ # Seed 2 : NaCl Signing Keypair
166
+ nacl_sig_sec_seed = secret_bytes[2].pack('C*').force_encoding('ASCII-8BIT')
167
+ nacl_sig_sec_key = RbNaCl::SigningKey.new(nacl_sig_sec_seed)
168
+ nacl_sig_pub_key = nacl_sig_sec_key.verify_key
169
+
170
+ # Seed 3 : Reserved for future use.
171
+ # Seed 4 : Reserved for future use.
172
+ # Seed 5 : Reserved for future use.
173
+ # Seed 6 : Reserved for future use.
174
+ # Seed 7 : Reserved for future use.
175
+
176
+ {
177
+ id: id_scrypt_hex,
178
+ nacl_simple_box: nacl_simple_box,
179
+ nacl_enc_pub_key: nacl_enc_pub_key,
180
+ nacl_enc_sec_key: nacl_enc_sec_key,
181
+ nacl_sig_pub_key: nacl_sig_pub_key,
182
+ nacl_sig_sec_key: nacl_sig_sec_key,
183
+ nacl_enc_pub_key_b64: Base64.strict_encode64(nacl_enc_pub_key.to_bytes),
184
+ nacl_sig_pub_key_b64: Base64.strict_encode64(nacl_sig_pub_key.to_bytes),
185
+ process_time: ((Time.now - start_processing_time)*1000).round(2)
186
+ }
187
+ end
188
+ end