opensecret 0.0.988 → 0.0.9925

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.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +56 -159
  3. data/bin/opensecret +2 -2
  4. data/bin/ops +17 -2
  5. data/lib/extension/string.rb +14 -16
  6. data/lib/{interpreter.rb → interprete.rb} +53 -29
  7. data/lib/keytools/binary.map.rb +49 -0
  8. data/lib/keytools/kdf.api.rb +249 -0
  9. data/lib/keytools/kdf.bcrypt.rb +64 -29
  10. data/lib/keytools/kdf.pbkdf2.rb +92 -83
  11. data/lib/keytools/kdf.scrypt.rb +190 -0
  12. data/lib/keytools/key.64.rb +326 -0
  13. data/lib/keytools/key.algo.rb +109 -0
  14. data/lib/keytools/key.api.rb +1281 -0
  15. data/lib/keytools/key.db.rb +265 -0
  16. data/lib/keytools/{key.module.rb → key.docs.rb} +55 -0
  17. data/lib/keytools/key.error.rb +110 -0
  18. data/lib/keytools/key.id.rb +271 -0
  19. data/lib/keytools/key.iv.rb +107 -0
  20. data/lib/keytools/key.local.rb +265 -0
  21. data/lib/keytools/key.mach.rb +248 -0
  22. data/lib/keytools/key.now.rb +402 -0
  23. data/lib/keytools/key.pair.rb +259 -0
  24. data/lib/keytools/key.pass.rb +120 -0
  25. data/lib/keytools/key.rb +428 -298
  26. data/lib/keytools/keydebug.txt +295 -0
  27. data/lib/logging/gem.logging.rb +3 -3
  28. data/lib/modules/cryptology/collect.rb +20 -0
  29. data/lib/session/require.gem.rb +1 -1
  30. data/lib/usecase/cmd.rb +417 -0
  31. data/lib/usecase/id.rb +36 -0
  32. data/lib/usecase/import.rb +174 -0
  33. data/lib/usecase/init.rb +78 -0
  34. data/lib/usecase/login.rb +70 -0
  35. data/lib/usecase/logout.rb +30 -0
  36. data/lib/usecase/open.rb +126 -0
  37. data/lib/{interprete → usecase}/put.rb +100 -47
  38. data/lib/usecase/read.rb +89 -0
  39. data/lib/{interprete → usecase}/safe.rb +0 -0
  40. data/lib/{interprete → usecase}/set.rb +0 -0
  41. data/lib/usecase/token.rb +111 -0
  42. data/lib/{interprete → usecase}/use.rb +0 -0
  43. data/lib/version.rb +1 -1
  44. data/opensecret.gemspec +4 -3
  45. metadata +39 -33
  46. data/lib/exception/cli.error.rb +0 -53
  47. data/lib/exception/errors/cli.errors.rb +0 -31
  48. data/lib/interprete/begin.rb +0 -232
  49. data/lib/interprete/cmd.rb +0 -621
  50. data/lib/interprete/export.rb +0 -163
  51. data/lib/interprete/init.rb +0 -205
  52. data/lib/interprete/key.rb +0 -119
  53. data/lib/interprete/open.rb +0 -148
  54. data/lib/interprete/seal.rb +0 -129
  55. data/lib/keytools/digester.rb +0 -245
  56. data/lib/keytools/key.data.rb +0 -227
  57. data/lib/keytools/key.derivation.rb +0 -341
  58. data/lib/modules/mappers/collateral.rb +0 -282
  59. data/lib/modules/mappers/envelope.rb +0 -127
  60. data/lib/modules/mappers/settings.rb +0 -170
  61. data/lib/notepad/scratch.pad.rb +0 -224
  62. data/lib/store-commands.txt +0 -180
@@ -234,6 +234,55 @@ cipher.key = key
234
234
 
235
235
  end
236
236
 
237
+
238
+ def self.binbytes
239
+
240
+ for n in 0 .. 256
241
+ eight_bit_binary = "%08d" % [ n.to_s(2) ]
242
+ puts "#{eight_bit_binary} => #{n}"
243
+ end
244
+
245
+ end
246
+
247
+
248
+ def self.shovel
249
+
250
+ first_name = "joe"
251
+ last_name = "bloggs"
252
+
253
+ user_name = first_name
254
+ user_name << last_name
255
+
256
+ puts "Username => #{user_name}"
257
+ puts "First name => #{first_name}"
258
+
259
+ end
260
+
261
+
262
+ def self.print_randoms
263
+ require 'securerandom'
264
+ for n in 0 .. 99
265
+ puts "#{from_rand}"
266
+ end
267
+
268
+ end
269
+
270
+
271
+ def self.from_rand
272
+ random_bit_string = ""
273
+ the_ints = Array.new
274
+ for n in 1 .. 48
275
+ random_integer = SecureRandom.random_number( 256 )
276
+ the_ints.push random_integer
277
+ random_bit_string += "%08d" % [ random_integer.to_s(2) ]
278
+ end
279
+ puts "Integers => #{the_ints.to_s}"
280
+ return random_bit_string
281
+ end
282
+
283
+ ## BinaryMap.print_randoms
284
+ ## BinaryMap.shovel
285
+ ## BinaryMap.binbytes
237
286
  ## BinaryMap.binary
238
287
  ## BinaryMap.crypter
239
288
  ## BinaryMap.bcrypter
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ module OpenKey
5
+
6
+ # The OpenKey underlying security strategy is to lock a master index file
7
+ # with a <b>symmetric encryption key</b> that is based on two randomly generated
8
+ # and amalgamated <b>55 and 45 character keys</b> and then to lock that key
9
+ # <b>(and only that key)</b> with a 256 bit symmetric encryption key derived from
10
+ # a human password and generated by at least two cryptographic workhorses known
11
+ # as <b>key derivation functions</b>.
12
+ #
13
+ # Random powerful keys are derived are seeded with 55 random bytes and
14
+ # then fed through the master key generator and its two key derivation
15
+ # functions (BCrypt and PBKDF2).
16
+ #
17
+ # == What Does the Master Encryption Key Generator Do?
18
+ #
19
+ # This class sits at the core of implementing that strategy and works to produce
20
+ # 256 bit encryption key derived from a human password which is then minced by
21
+ # two best of breed key derivation functions (BCrypt and PBKDF2).
22
+ #
23
+ # BCrypt (Blowfish) and PBKDF2 are the leading <b>key derivation functions</b>
24
+ # whose modus operandi is to convert <b>low entropy</b> human generated passwords
25
+ # into a high entropy key that is computationally infeasible to acquire via brute
26
+ # force.
27
+ #
28
+ # == How to Create the Encryption Key
29
+ #
30
+ # To create a high entropy encryption key this method takes the first
31
+ # 168 bits from the 186 bit BCrypt key produced by {KdfBCrypt} and
32
+ # the first 96 bits from the 132 bit PBKDF2 key produced inside the
33
+ # {KeyPbkdf2} class and amalgamates them to produce a 264 bit key.
34
+ #
35
+ # The 264 bit key is then digested to produce a 256bit encryption key.
36
+ class KdfApi
37
+
38
+
39
+ # BCrypt (Blowfish) and PBKDF2 are the leading <b>key derivation functions</b>
40
+ # whose modus operandi is to convert <b>low entropy</b> human generated passwords
41
+ # into a high entropy key that is computationally infeasible to acquire via brute
42
+ # force.
43
+ BCRYPT_SALT_KEY_NAME = "bcrypt.salt"
44
+
45
+
46
+ # BCrypt (Blowfish) and PBKDF2 are the leading <b>key derivation functions</b>
47
+ # whose modus operandi is to convert <b>low entropy</b> human generated passwords
48
+ # into a high entropy key that is computationally infeasible to acquire via brute
49
+ # force.
50
+ PBKDF2_SALT_KEY_NAME = "pbkdf2.salt"
51
+
52
+
53
+ # To create a high entropy encryption key we use the full 180 bits
54
+ # from the returned 180 bit BCrypt key produced by {KdfBCrypt}.
55
+ #
56
+ # When amalgamated with the <b>332 bits from the PBKDF2 Key</b> we
57
+ # achieve a powerful <b>union key length</b> of 512 bits.
58
+ BCRYPT_KEY_CONTRIBUTION_SIZE = 180
59
+
60
+
61
+ # The first 332 bits are used from the 384 bit key returned by the
62
+ # PBKDF2 algorithm.
63
+ #
64
+ # When amalgamated with the <b>180 bits from the BCrypt Key</b> we
65
+ # achieve a powerful <b>union key length</b> of 512 bits.
66
+ PBKDF2_KEY_CONTRIBUTION_SIZE = 332
67
+
68
+
69
+ # To create a high entropy encryption key we use the full 180 bits
70
+ # from the returned 180 bit BCrypt key produced by {KdfBCrypt} and
71
+ # the first 332 bits from the 384 bit key returned by PBKDF2.
72
+ #
73
+ # On amalgamation, the outcome is a quality <b>union key length</b>
74
+ # of <b>512 bits</b>.
75
+ AMALGAM_KEY_RAW_BIT_SIZE = BCRYPT_KEY_CONTRIBUTION_SIZE + PBKDF2_KEY_CONTRIBUTION_SIZE
76
+
77
+
78
+ # This method generates a 256 bit symmetric encryption key by passing a
79
+ # textual human sourced secret into two <b>key derivation functions</b>,
80
+ # namely <b>BCrypt and PBKDF2</b>. BCrypt, PBKDF2 and SCrypt are today's
81
+ # <b>in form best of breed</b> cryptographic workhorses for producing a
82
+ # high entropy key from possibly weak human sourced secret text.
83
+ #
84
+ # <b>Example | Derive Key from Password</b>
85
+ #
86
+ # key_store = KeyPair.new( "/path/to/kdf-salt-data.ini" )
87
+ # key_store.use( "peter-pan" )
88
+ # human_key = KdfApi.generate_from_password( "my_s3cr3t", key_store )
89
+ #
90
+ # strong_key = Key.from_random()
91
+ # human_key.encrypt_key( strong_key, key_store )
92
+ #
93
+ # strong_key.encrypt_file "/path/to/file-to-encrypt.pdf"
94
+ # strong_key.encrypt_text "I am the text to encrypt."
95
+ #
96
+ # ---
97
+ #
98
+ # <b>Do not use the key derived from a human secret</b> to encrypt anything
99
+ # other than a <b>high entropy key</b> randomly sourced from 48 bytes.
100
+ #
101
+ # Every time the user logs in, generate (recycle), another human key and
102
+ # another strong key and discard the previously outputted cipher texts.
103
+ #
104
+ # == BCrypt and the PBKDF2 Cryptographic Algorithms
105
+ #
106
+ # BCrypt (Blowfish) and PBKDF2 are the leading <b>key derivation functions</b>
107
+ # that exists to convert <b>low entropy</b> human generated passwords into a high
108
+ # entropy key that is computationally infeasible to acquire through brute force.
109
+ #
110
+ # To create a high entropy encryption key we use the full 180 bits
111
+ # from the returned 180 bit BCrypt key produced by {KdfBCrypt} and
112
+ # the first 332 bits from the 384 bit key returned by PBKDF2.
113
+ #
114
+ # On amalgamation, the outcome is a quality <b>union key length</b>
115
+ # of <b>512 bits</b>.
116
+ #
117
+ # == Creating a High Entropy Encryption Key
118
+ #
119
+ # To create a high entropy encryption key this method takes the first
120
+ # 168 bits from the 186 bit BCrypt key produced by {KdfBCrypt} and
121
+ # the first 96 bits from the 132 bit PBKDF2 key produced inside the
122
+ # {KeyPbkdf2} class and amalgamates them to produce a 264 bit key.
123
+ #
124
+ # Note that all four of the above numbers are divisable by six (6), for
125
+ # representation with a 64 character set, and eight (8), for transport
126
+ # via the byte (8 bit) protocols.
127
+ #
128
+ # <b>Size of BCrypt and PBKDF2 Derived Keys</b>
129
+ #
130
+ # + --------- - --------- +
131
+ # + --------- | --------- +
132
+ # | Algorithm | Bit Count |
133
+ # ----------- | --------- |
134
+ # | BCrypt | 180 Bits |
135
+ # | Pbkdf2 | 332 Bits |
136
+ # ----------- | --------- |
137
+ # | Total | 512 Bits |
138
+ # + --------- | --------- +
139
+ # + --------- - --------- +
140
+ #
141
+ # <b>256 Bit Encryption Key | Remove 8 Bits</b>
142
+ #
143
+ # The manufactured encryption key, an amalgam of the above now has
144
+ # 264 bits carried by 44 Base64 characters.
145
+ #
146
+ # Just before it is used to encrypt vital keys, eight (8) bits are
147
+ # removed from the end of the key. The key is then converted into a
148
+ # powerful 32 byte (256 bit) encryption agent and is hashed by the
149
+ # SHA256 digest and delivered.
150
+ #
151
+ # @param human_secret [String]
152
+ # a robust human generated password with as much entropy as can
153
+ # be mustered. Remember that 40 characters spread randomly over
154
+ # the key space of about 90 characters and not relating to any
155
+ # dictionary word or name is the way to generate a powerful key
156
+ # that has embedded a near 100% entropy rating.
157
+ #
158
+ # @param key_map [KeyPair]
159
+ # The KeyPair storage service must have been initialized and a
160
+ # section specified using {KeyPair.use} thus allowing this method
161
+ # to <b>write key-value pairs</b> representing the BCrypt and
162
+ # PBKDF2 salts through the {KeyPair.set} behaviour.
163
+ #
164
+ # @return [Key]
165
+ # the 256 bit symmetric encryption key derived from a human password
166
+ # and passed through two cryptographic workhorses.
167
+ def self.generate_from_password human_secret, key_map
168
+
169
+ bcrypt_salt = KdfBCrypt.generate_bcrypt_salt
170
+ pbkdf2_salt = KeyPbkdf2.generate_pbkdf2_salt
171
+
172
+ key_map.set( BCRYPT_SALT_KEY_NAME, bcrypt_salt )
173
+ key_map.set( PBKDF2_SALT_KEY_NAME, pbkdf2_salt )
174
+
175
+ return derive_and_amalgamate( human_secret, bcrypt_salt, pbkdf2_salt )
176
+
177
+ end
178
+
179
+
180
+ # Regenerate the viciously unretrievable nor reversable key that was
181
+ # generated in the past and with the same salts that were used during
182
+ # the original key derivation process.
183
+ #
184
+ # @param key_map [Hash]
185
+ # an instantiated and populated hash object containing the salts
186
+ # which were created in the past during the generation. These are
187
+ # now vital for a successful regeneration.
188
+ #
189
+ # @return [Key]
190
+ # the 256 bit symmetric encryption key that was previously generated
191
+ # from the secret and the cryptographic salts within the key_map.
192
+ def self.regenerate_from_salts human_secret, key_map
193
+
194
+ bcrypt_salt = key_map.get( BCRYPT_SALT_KEY_NAME )
195
+ pbkdf2_salt = key_map.get( PBKDF2_SALT_KEY_NAME )
196
+
197
+ return derive_and_amalgamate( human_secret, bcrypt_salt, pbkdf2_salt )
198
+
199
+ end
200
+
201
+
202
+
203
+ private
204
+
205
+
206
+
207
+ def self.derive_and_amalgamate( human_secret, bcrypt_salt, pbkdf2_salt )
208
+
209
+ bcrypt_key = OpenKey::KdfBCrypt.generate_key( human_secret, bcrypt_salt )
210
+ pbkdf2_key = OpenKey::KeyPbkdf2.generate_key( human_secret.reverse, pbkdf2_salt )
211
+
212
+ assert_bcrypt_key_bit_length bcrypt_key
213
+ assert_pbkdf2_key_bit_length pbkdf2_key
214
+
215
+ amalgam_key = Key.new ( bcrypt_key.to_s[ 0 .. (BCRYPT_KEY_CONTRIBUTION_SIZE-1) ] + pbkdf2_key.to_s[ 0 .. (PBKDF2_KEY_CONTRIBUTION_SIZE-1) ] )
216
+
217
+ assert_amalgam_key_bit_length amalgam_key
218
+
219
+ return amalgam_key
220
+
221
+ end
222
+
223
+
224
+ def self.assert_bcrypt_key_bit_length bcrypt_key
225
+ bcrypt_key_bit_length = bcrypt_key.to_s.bytesize
226
+ bcrypt_keysize_msg = "Expecting #{KdfBCrypt::BCRYPT_KEY_EXPORT_BIT_LENGTH} not #{bcrypt_key_bit_length} bits in bcrypt key."
227
+ raise RuntimeError, bcrypt_keysize_msg unless bcrypt_key_bit_length == KdfBCrypt::BCRYPT_KEY_EXPORT_BIT_LENGTH
228
+ end
229
+
230
+
231
+ def self.assert_pbkdf2_key_bit_length pbkdf2_key
232
+ pbkdf2_key_bit_length = pbkdf2_key.to_s.bytesize
233
+ pbkdf2_keysize_msg = "Expecting #{KeyPbkdf2::PBKDF2_EXPORT_BIT_LENGTH} not #{pbkdf2_key_bit_length} bits in pbkdf2 key."
234
+ raise RuntimeError, pbkdf2_keysize_msg unless pbkdf2_key_bit_length == KeyPbkdf2::PBKDF2_EXPORT_BIT_LENGTH
235
+ end
236
+
237
+
238
+ def self.assert_amalgam_key_bit_length amalgam_key
239
+
240
+ amalgam_key_bit_length = amalgam_key.to_s.bytesize
241
+ amalgam_keysize_msg = "Expecting #{AMALGAM_KEY_RAW_BIT_SIZE} not #{amalgam_key_bit_length} bits in amalgam key."
242
+ raise RuntimeError, amalgam_keysize_msg unless amalgam_key_bit_length == AMALGAM_KEY_RAW_BIT_SIZE
243
+ end
244
+
245
+
246
+ end
247
+
248
+
249
+ end
@@ -21,12 +21,10 @@ module OpenKey
21
21
  #
22
22
  # The <b>minimum cost</b> is 4 (16 iterations) and the maximum is 31.
23
23
  #
24
- # <b>A cost of 16 will result in 2^16 = 65,536 iterations</b>.
24
+ # <b>A cost of 16 will result in 2^16 = 65,536 iterations</b> and will slow the
25
+ # derivation time to about a second on a powerful 2020 laptop.
25
26
  #
26
- # This is a safe default and will slow the derivation time
27
- # to about a second on a powerful 2020 laptop.
28
- #
29
- class BCryptKeyGen
27
+ class KdfBCrypt
30
28
 
31
29
  require "bcrypt"
32
30
 
@@ -50,20 +48,21 @@ module OpenKey
50
48
  BCRYPT_KEY_LENGTH = 31
51
49
 
52
50
 
53
- # When the key is transported using a 64 character set where
54
- # each character is represented by 6 bits - the BCrypt key
55
- # expands to 186 bits rather than the original 181 bits.
56
- #
57
- # This expansion is because of the remainder.
58
- #
59
- # 181 bits divided by 6 is 30 characters plus 1 character
60
- # for the extra bit.
51
+ # BCrypt key derivation (from text) implementations truncate
52
+ # the first 55 characters of the incoming text.
53
+ BCRYPT_MAX_IN_TEXT_LENGTH = 55
54
+
55
+
56
+ # The BCrypt algorithm produces 181 raw binary bits which is just
57
+ # one bit more than a 30 character base64 string. Hence the algorithm
58
+ # puts out 31 characters.
61
59
  #
62
- # The 31 transported characters then appear as
63
- # 31 times 6 which equals 186 bits.
64
- BCRYPT_KEY_TRANSPORT_LENGTH = 186
60
+ # We discard the 31st character because 5 of its 6 bits are 100%
61
+ # predictable. Thus the returned key will contribute 180 bits.
62
+ BCRYPT_KEY_EXPORT_BIT_LENGTH = 180
63
+
65
64
 
66
- # The bcrypt algorithm salt string should be 22 characters
65
+ # The BCrypt algorithm salt string should be 22 characters
67
66
  # and may include forward slashes and periods.
68
67
  BCRYPT_SALT_LENGTH = 22
69
68
 
@@ -78,7 +77,7 @@ module OpenKey
78
77
  # The two sections are the
79
78
  # - BCrypt algorithm <b>version number</b> (2a or 2b) and
80
79
  # - a power of 2 integer defining the no. of interations
81
- BCRYPT_OUTPUT_TEXT_PREFIX = "$2a$#{BCRYPT_ITERATION_INTEGER}$"
80
+ BCRYPT_OUTPUT_TEXT_PREFIX = "$2x$#{BCRYPT_ITERATION_INTEGER}$"
82
81
 
83
82
 
84
83
  # Key generators should use this method to create a BCrypt salt
@@ -101,15 +100,45 @@ module OpenKey
101
100
  # This method removes the $2a$16$ preamble string and stores only
102
101
  # the actual salt string whose length should be 22 characters.
103
102
  #
103
+ # <b>Why do BCrypt salts always end with zero, e, u or period</b>?
104
+ #
105
+ # Two <b>(2) leftover bits</b> is the short answer.
106
+ #
107
+ # This is because the salts are a random 16 bytes and must be
108
+ # stored in base64. The 16 bytes equals 128bits which when converted
109
+ # to base64 (6bits per character) results in 21 characters and only
110
+ # two leftover bits.
111
+ #
112
+ # BCrypt Salt => t4bDqoJlHbb/k7bkt4/1Ku (22 characters)
113
+ # BCrypt Salt => 9BjuJU67IG9Lz5tYUhOqeO (22 characters)
114
+ # BCrypt Salt => grz.QREI35585Y3AaCoCTe (22 characters)
115
+ # BCrypt Salt => zsxrVW2RGIltSu.AoS4E7e (22 characters)
116
+ # BCrypt Salt => dTlRJZ6ijDDVk2cFoCQHPO (22 characters)
117
+ # BCrypt Salt => S9B1azH7oD8L3.CQfxxzJO (22 characters)
118
+ # BCrypt Salt => LoZh.q3NdnTIuOmR6gHJF. (22 characters)
119
+ # BCrypt Salt => y6DKk23SmgNR863pTZ8nYe (22 characters)
120
+ # BCrypt Salt => rokdUF6tg6wHV6F0ymKFme (22 characters)
121
+ # BCrypt Salt => jrDpNgh.0OEIYaxsR7E7d. (22 characters)
122
+ #
123
+ # Don't forget BCrypt uses Radix64 (from OpenBSD). So the two (2)
124
+ # leftover bits result in 4 possible values which effectively is
125
+ #
126
+ # a period (.)
127
+ # a zero (0)
128
+ # an e (e)
129
+ # or a u (u)
130
+ #
104
131
  # @return [String]
105
132
  # the salt in a printable format like base64, hex or a string
106
133
  # of ones and zeroes. This salt should be submitted in the exact
107
134
  # same form to the {generate_key} method.
108
- def self.generate_salt
135
+ def self.generate_bcrypt_salt
136
+
109
137
  the_salt_str = BCrypt::Engine.generate_salt( BCRYPT_ITERATION_INTEGER )
110
138
  bcrypt_salt = the_salt_str[ BCRYPT_OUTPUT_TEXT_PREFIX.length .. -1 ]
111
139
  assert_bcrypt_salt bcrypt_salt
112
140
  return bcrypt_salt
141
+
113
142
  end
114
143
 
115
144
 
@@ -141,19 +170,30 @@ module OpenKey
141
170
  # resubmitted here (in the future) to regenerate the same key.
142
171
  #
143
172
  # @return [Key]
144
- # a key holder containing the key which can then be accessed via
145
- # many different formats.
173
+ # an {OpenKey::Key} that has been initialized from the 30 RADIX64
174
+ # character output from the BCrypt algorithm.
175
+ #
176
+ # The BCrypt algorithm produces 181 raw binary bits which is just
177
+ # one bit more than a 30 character base64 string. Hence the algorithm
178
+ # puts out 31 characters.
179
+ #
180
+ # We discard the 31st character because 5 of its 6 bits are 100%
181
+ # predictable. Thus the returned key will contribute 180 bits.
146
182
  def self.generate_key human_secret, bcrypt_salt
147
183
 
148
- hashed_secret = BCrypt::Engine.hash_secret( human_secret, to_bcrypt_salt(bcrypt_salt) )
184
+ assert_bcrypt_salt( bcrypt_salt )
185
+ full_bcrypt_salt = BCRYPT_OUTPUT_TEXT_PREFIX + bcrypt_salt
186
+ hashed_secret = BCrypt::Engine.hash_secret( human_secret, full_bcrypt_salt )
149
187
  encoded64_key = BCrypt::Password.new( hashed_secret ).to_s
150
188
 
151
189
  key_begin_index = BCRYPT_OUTPUT_TEXT_PREFIX.length + BCRYPT_SALT_LENGTH
152
190
  radix64_key_str = encoded64_key[ key_begin_index .. -1 ]
153
- key_length_mesg = "The bcrypt key length should have #{BCRYPT_KEY_LENGTH} characters."
191
+ key_length_mesg = "The BCrypt key length should have #{BCRYPT_KEY_LENGTH} characters."
154
192
  raise RuntimeError, key_length_mesg unless radix64_key_str.length == BCRYPT_KEY_LENGTH
155
193
 
156
- return Key.new(radix64_key_str)
194
+ chopped_radix64_key = radix64_key_str.chop()
195
+
196
+ return Key.from_radix64( chopped_radix64_key )
157
197
 
158
198
  end
159
199
 
@@ -162,11 +202,6 @@ module OpenKey
162
202
  private
163
203
 
164
204
 
165
-
166
- def self.to_bcrypt_salt the_salt
167
- return BCRYPT_OUTPUT_TEXT_PREFIX + the_salt
168
- end
169
-
170
205
  def self.assert_bcrypt_salt the_salt
171
206
  raise RuntimeError, "bcrypt salt not expected to be nil." if the_salt.nil?
172
207
  salt_length_msg = "A bcrypt salt is expected to contain #{BCRYPT_SALT_LENGTH} characters."