opensecret 0.0.951 → 0.0.957

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/extension/array.rb +29 -0
  3. data/lib/extension/string.rb +31 -0
  4. data/lib/factbase/facts.opensecret.io.ini +17 -9
  5. data/lib/notepad/blow.rb +108 -5
  6. data/lib/opensecret.rb +32 -6
  7. data/lib/plugins/cipher.rb +7 -7
  8. data/lib/plugins/ciphers/blowfish.rb +63 -157
  9. data/lib/plugins/usecase.rb +1 -1
  10. data/lib/plugins/usecases/init.rb +57 -116
  11. data/lib/plugins/usecases/lock.rb +178 -0
  12. data/lib/plugins/usecases/open.rb +17 -86
  13. data/lib/plugins/usecases/put.rb +137 -0
  14. data/lib/plugins/usecases/safe.rb +8 -10
  15. data/lib/session/attributes.rb +16 -11
  16. data/lib/session/dictionary.rb +191 -0
  17. data/lib/session/session.rb +80 -0
  18. data/lib/session/time.stamp.rb +89 -106
  19. data/lib/using.txt +100 -0
  20. data/lib/version.rb +1 -1
  21. metadata +6 -15
  22. data/lib/opensecret/commons/eco.faculty.rb +0 -364
  23. data/lib/opensecret/commons/eco.system.rb +0 -437
  24. data/lib/opensecret/commons/eco.systems.rb +0 -98
  25. data/lib/opensecret/factbase/hub-runtime.ini +0 -123
  26. data/lib/opensecret/factbase/known-hosts.ini +0 -75
  27. data/lib/opensecret/factbase/published.facts/blobbolicious-facts.ini +0 -553
  28. data/lib/opensecret/factbase/published.facts/credential-facts.ini +0 -40
  29. data/lib/opensecret/factbase/published.facts/infrastructure-facts.ini +0 -63
  30. data/lib/opensecret/factbase/readme.md +0 -24
  31. data/lib/opensecret/factbase/retired.facts/maven.database.ide.facts.ini +0 -127
  32. data/lib/opensecret/factbase/retired.facts/s3-upload-block-facts.ini +0 -17
  33. data/lib/opensecret/plugins.io/file/file.rb +0 -483
  34. data/lib/plugins/usecases/on.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca35c2727f92f764b83fae65d656062b95520ad6
4
- data.tar.gz: 260748f11554e881116e6efd8c4d44c0cdb06284
3
+ metadata.gz: 9681f58d24288c4f1b13d0b83187dff72f9909f5
4
+ data.tar.gz: 850a7fc15a960497f1f6b209d7f30a9c1b26b2fd
5
5
  SHA512:
6
- metadata.gz: 10f94cba6fe468750401a38846641c9dddce2258601d981b1fb26e5b2e88c7fea27edb10264ee070d3d4920c6ada9470e0a7b4cb3178a5f5c2a07facb186db1a
7
- data.tar.gz: 35aa0ff66488c53859c245c10ba2d3aae348b56df4df90d94963241b190b8065f39f20bbfb63c119159f25488b8262f69f847fd1a3e715d3fe8df13954cbc921
6
+ metadata.gz: a3e87ecc9eaf58507d26d92ab6665a3cc4f5f0ea86a1b577b685394af57e6c8db0b2271d399eb9100beb3acf301e863ee43c17a3a7f58751626f6a5264ffbb38
7
+ data.tar.gz: 626b3bbdc2becea5b6d1dfa4eefac208a8dca4d33504598e0e7d6bef6a05629188a2cae69edb981a21db8b6fca1bc2e7af9ed1d3a421b26bfe071f061c3c9dbc
@@ -12,6 +12,35 @@
12
12
  class Array
13
13
 
14
14
 
15
+ # The returned string is a result of a union (join) of all the
16
+ # (expected) string array elements followed by the <b>deletion</b>
17
+ # of <b>all <em>non</em> alphanumeric characters</b>.
18
+ #
19
+ # <b>Disambiguating the String for Cross Platform Use</b>
20
+ #
21
+ # This behaviour is typically used for transforming text that is
22
+ # about to be signed or digested (hashed). Removing all the non
23
+ # alpha-numeric characters disambiguates the string.
24
+ #
25
+ # An example is the exclusion of line ending characters which in
26
+ # Windows are different from Linux.
27
+ #
28
+ # This disambiguation means that signing functions will return the
29
+ # same result on widely variant platfoms like Windows vs CoreOS.
30
+ #
31
+ # @return [String]
32
+ # Returns the alphanumeric union of the strings within this array.
33
+ #
34
+ # @raise [ArgumentError]
35
+ # if the array is nil or empty. Also an error will be thrown if
36
+ # the array contains objects that cannot be naturally converted
37
+ # to a string.
38
+ def alphanumeric_union
39
+ raise ArgumentError, "Cannot do alphanumeric union on an empty array." if self.empty?
40
+ return self.join.to_alphanumeric
41
+ end
42
+
43
+
15
44
  # Log the array using our logging mixin by printing every array
16
45
  # item into its own log line. In most cases we (the array) are
17
46
  # a list of strings, however if not, each item's to_string method
@@ -12,6 +12,37 @@
12
12
  class String
13
13
 
14
14
 
15
+ # Return a new string matching this one with every non alpha-numeric
16
+ # character removed. This string is left unchanged.
17
+ #
18
+ # Spaces, hyphens, underscores, periods are all removed. The only
19
+ # characters left standing belong to a set of 62 and are
20
+ #
21
+ # - a to z
22
+ # - A to Z
23
+ # - 0 to 9
24
+ #
25
+ # @return [String]
26
+ # Remove any character that is not alphanumeric, a to z, A to Z
27
+ # and 0 to 9 and return a new string leaving this one unchanged.
28
+ def to_alphanumeric
29
+ return self.delete("^A-Za-z0-9")
30
+ end
31
+
32
+
33
+ # Find the length of this string and return a string that is the
34
+ # concatenated union of this string and its integer length.
35
+ # If this string is empty a string of length one ie "0" will be
36
+ # returned.
37
+ #
38
+ # @return [String]
39
+ # Return this string with a cheeky integer tagged onto the end
40
+ # that represents the (pre-concat) length of the string.
41
+ def concat_length
42
+ return self + "#{self.length}"
43
+ end
44
+
45
+
15
46
  # Get the text [in between] this and that delimeter [exclusively].
16
47
  # Exclusively means the returned text [does not] include either of
17
48
  # the matched delimeters (although an unmatched instance of [this]
@@ -8,19 +8,27 @@ root.domain = devopswiki.co.uk
8
8
  env.var.name = SECRET_MATERIAL
9
9
  ratio = rb>> 3
10
10
  bit.key.size = rb>> 8192
11
- key.cipher = rb>> OpenSSL::Cipher.new 'AES-256-CBC'
12
- secret.keydir = rb>> OpenSession::Attributes.instance.get_value @s[:name], "safe"
13
- email.address = rb>> OpenSession::Attributes.instance.get_value @s[:name], "email"
11
+ key.cipher = rb>> OpenSSL::Cipher::AES256.new(:CBC)
12
+ secret.keydir = rb>> OpenSession::Attributes.instance.get_value @s[:name], @s[:name], "safe"
13
+ email.address = rb>> OpenSession::Attributes.instance.get_value @s[:name], @s[:name], "email"
14
14
  safe.user = rb>> File.join @s[:secret_keydir], @s[:email_address]
15
15
  master.dirname = master.keys
16
16
  master.dirpath = rb>> File.join @s[:safe_user], @s[:master_dirname]
17
- master.pub.name = master.public.key.x.os.txt
18
- master.prv.name = master.private.key.x.os.txt
19
- master.pub.key = rb>> File.join @s[:master_dirpath], @s[:master_pub_name]
17
+
18
+ master.sig.file = master.signature.os.txt
19
+ ########### -----> master.pub.name = master.public.key.os.txt
20
+ master.prv.name = master.private.key.xx.txt
21
+ master.sig.path = rb>> File.join @s[:master_dirpath], @s[:master_sig_file]
22
+ ########### -----> master.pub.key = rb>> File.join @s[:master_dirpath], @s[:master_pub_name]
20
23
  master.prv.key = rb>> File.join @s[:master_dirpath], @s[:master_prv_name]
21
24
 
22
- machine.key.x = machine.key.x
25
+ stamp.key = stamp
26
+ stamp.14 = rb>> OpenSession::Stamp.yyjjj_hhmm_sst
27
+ stamp.23 = rb>> OpenSession::Stamp.yyjjj_hhmm_ss_nanosec
28
+
29
+ machine.key.x = os.x
23
30
  separator.a = %$os$%
31
+ publickey.id = public.key
24
32
 
25
33
  repo.name = material_data
26
34
 
@@ -32,8 +40,8 @@ prompt.2 = Re-enter that Password
32
40
  open.name = session
33
41
  open.dirname = session.material
34
42
  open.dirpath = rb>> File.join @f[:global][:safe_user], @s[:open_dirname]
35
- open.idlen = 9
36
- open.keylen = 96
43
+ open.idlen = rb>> 10
44
+ open.keylen = rb>> 56
37
45
  open.idname = session.id
38
46
  open.keyname = session.key
39
47
  open.pathname = session.path
data/lib/notepad/blow.rb CHANGED
@@ -10,19 +10,75 @@
10
10
  class Trial
11
11
 
12
12
 
13
+ def self.certify
14
+
15
+ require 'openssl'
16
+ require "base64"
17
+
18
+ key = OpenSSL::PKey::RSA.new(1024)
19
+ public_key = key.public_key
20
+
21
+ subject = "/C=BE/O=Test/OU=Test/CN=Test"
22
+
23
+ cert = OpenSSL::X509::Certificate.new
24
+ cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject)
25
+ cert.not_before = Time.now
26
+ cert.not_after = Time.now + 365 * 24 * 60 * 60
27
+ cert.public_key = public_key
28
+ cert.serial = 0x0
29
+ cert.version = 2
30
+
31
+ ef = OpenSSL::X509::ExtensionFactory.new
32
+ ef.subject_certificate = cert
33
+ ef.issuer_certificate = cert
34
+ cert.extensions = [
35
+ ef.create_extension("basicConstraints","CA:TRUE", true),
36
+ ef.create_extension("subjectKeyIdentifier", "hash"),
37
+ # ef.create_extension("keyUsage", "cRLSign,keyCertSign", true),
38
+ ]
39
+ cert.add_extension ef.create_extension("authorityKeyIdentifier",
40
+ "keyid:always,issuer:always")
41
+
42
+ cert.sign key, OpenSSL::Digest::SHA1.new
43
+
44
+ puts cert.to_pem
45
+
46
+ end
47
+
48
+
49
+ ##### -----> Trial.certify
50
+
51
+
13
52
  def self.crypt
14
53
 
15
54
  require 'openssl'
16
55
  require "base64"
17
56
 
18
- key = OpenSSL::PKey::RSA.new(8192)
57
+ =begin
58
+ puts ""
59
+ puts Time.now.strftime "%9N"
60
+ puts Time.now.strftime "%12N"
61
+ puts Time.now.strftime "%15N"
62
+ puts Time.now.strftime "%18N"
63
+ puts ""
64
+ exit
65
+ =end
66
+
67
+ ## --------------------------------------------------------------------------------------------
68
+ ## --------------------------------------------------------------------------------------------
69
+
70
+ key = OpenSSL::PKey::RSA.new(2048)
19
71
 
20
72
 
21
73
  payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e337252c5407afd4895a5e3a2415fce5b703a483da3edc88739cb7787262a19d69fb9416f900fed797c046aaec83b8e15b14edb032ed76535def8ada77108936e5442a839d4078048ca01449a6acd7315c9b7a7b8802dba0c83eb4c13e21b1051efa77a420a3ffd3cbf1fa13182933a0503f23cce95b68787081f3af33c69049657bdbf1fd30d79f108d604faad1fbee198a3e2c1b28cdddf7ebb84b6b0c1d3e9b47665bd96d7df8407e11d00e4d9275e805c7b9e61b6739802d6d87ac8283ef92a593ed53db2096cd1dc9496307f40942cc3d54a7c864ede71e0b192ce152"
22
74
 
75
+ puts ""
76
+ puts ""
77
+ puts public_key_text = key.public_key.to_pem
23
78
  puts ""
24
79
  puts "Payload size is #{payload.length}"
25
80
  puts ""
81
+ =begin
26
82
  puts ""
27
83
  puts encrypted_string = key.public_encrypt( payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
28
84
  puts ""
@@ -38,9 +94,55 @@ payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e33
38
94
  puts ""
39
95
  puts encrypted_string.unpack("H*").first
40
96
  puts ""
41
- puts key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
42
97
  puts ""
43
-
98
+ puts "Padding => #{OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING}"
99
+ puts ""
100
+ puts key.private_decrypt( encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING )
101
+ puts ""
102
+ =end
103
+ email_address = "bob@hotmail.com"
104
+ time_stamp = "5th.April.2020.20:21pm"
105
+
106
+ secured_privatekey = key.export( OpenSSL::Cipher::AES256.new(:CBC), "secret12345abcde" )
107
+
108
+
109
+ second_key = OpenSSL::PKey::RSA.new(2048)
110
+ second_public_key_text = second_key.public_key.to_pem
111
+
112
+ context_string_dirty = secured_privatekey + public_key_text + email_address + time_stamp
113
+ context_string_clean = context_string_dirty.delete("^A-Za-z0-9")
114
+ context_string_clean += context_string_clean.length.to_s
115
+ #### context_signature_str = Base64.encode64(second_key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
116
+ context_signature_str = Base64.encode64(key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
117
+
118
+
119
+ ## --------------------------------------------------------------------------------------------
120
+ ## --------------------------------------------------------------------------------------------
121
+
122
+ reinstated_key = OpenSSL::PKey::RSA.new "#{public_key_text}"
123
+ ### reinstated_key = OpenSSL::PKey::RSA.new "#{second_public_key_text}"
124
+ raw_signature_text = Base64.decode64(context_signature_str)
125
+ is_valid = reinstated_key.public_key.verify OpenSSL::Digest::SHA256.new, raw_signature_text, (context_string_clean)
126
+ raise ArgumentError, "Keys not validated" unless is_valid
127
+
128
+ ## --------------------------------------------------------------------------------------------
129
+ ## --------------------------------------------------------------------------------------------
130
+
131
+ puts "======================================================================================"
132
+ puts "======================================================================================"
133
+ puts context_string_dirty
134
+ puts "======================================================================================"
135
+ puts "======================================================================================"
136
+ puts context_string_clean
137
+ puts "======================================================================================"
138
+ puts "======================================================================================"
139
+ puts context_signature_str
140
+ puts "======================================================================================"
141
+ puts "======================================================================================"
142
+ puts "Keys Are Valid => #{is_valid}"
143
+ puts "======================================================================================"
144
+ puts "======================================================================================"
145
+ puts ""
44
146
 
45
147
  end
46
148
 
@@ -55,8 +157,9 @@ HNkUjWaFoI5dPTRUUymyf7uKMaXFhiIZaOq+ZYj4TWPN92qv6ANTd3pRvVa3
55
157
  S+aQSOX7q3FkKIOc5yfWLushGAMSwidgH1kzLvocCf+SSWH5BY3zTb7NAGjW
56
158
  =end
57
159
 
58
- ### Trial.crypt
59
- ### exit
160
+ # -------->
161
+ # --------> Trial.crypt
162
+ # -------->
60
163
 
61
164
  def try
62
165
 
data/lib/opensecret.rb CHANGED
@@ -32,7 +32,9 @@ OpenSession::RecursivelyRequire.now( __FILE__ )
32
32
  #
33
33
  class CliInterpreter < Thor
34
34
 
35
- log.info(x) {"Wake up loggers."}
35
+ OpenSession::Session.instance.context = "opensecret"
36
+ log.info(x) {"opensecret session initiated at [#{OpenSession::Stamp.yyjjj_hhmm_sst}]." }
37
+ log.info(x) {"opensecret session context is [#{OpenSession::Session.instance.context}]." }
36
38
 
37
39
  #
38
40
  # This class option allows every CLI call the option to include
@@ -55,12 +57,36 @@ class CliInterpreter < Thor
55
57
 
56
58
 
57
59
  # Description of the open "wake-up" call.
58
- desc "open", "open up a conduit for adding, subtracting and swapping secrets for a future commit."
60
+ desc "open CONTEXT_PATH", "CONTEXT_PATH context path to the family of secrets to be created."
59
61
 
60
62
  # Open up a conduit from which we can add, subtract, update and list secrets
61
63
  # before they are committed (and pushed) into permanent locked storage.
62
- def open
63
- OpenSecret::Open.new.flow_of_events
64
+ #
65
+ # @param context_path [String] the path to USB key for storing encrypted keys
66
+ def open context_path
67
+
68
+ open_uc = OpenSecret::Open.new
69
+ open_uc.context_path = context_path
70
+ open_uc.flow_of_events
71
+
72
+ end
73
+
74
+
75
+ # Description of the put secret command.
76
+ desc "put <secret_id> <secret_value>", "put secret like login/username into opened context."
77
+
78
+ # Put a secret with an id like login/username and a value like joebloggs into the
79
+ # context (eg work/laptop) that was opened with the open command.
80
+ #
81
+ # @param secret_id [String] the id of the secret to put into the opened context
82
+ # @param secret_value [String] the value of the secret to put into the opened context
83
+ def put secret_id, secret_value
84
+
85
+ put_uc = OpenSecret::Put.new
86
+ put_uc.secret_id = secret_id
87
+ put_uc.secret_value = secret_value
88
+ put_uc.flow_of_events
89
+
64
90
  end
65
91
 
66
92
 
@@ -120,7 +146,7 @@ class CliInterpreter < Thor
120
146
  abort "The tiniest (externally accessible) email address [a@b.cd] has 6 characters."
121
147
  end
122
148
 
123
- OpenSession::Attributes.stash "opensecret", "email", email_address
149
+ OpenSession::Attributes.stash "opensecret", "opensecret", "email", email_address
124
150
 
125
151
  end
126
152
 
@@ -147,7 +173,7 @@ class CliInterpreter < Thor
147
173
  abort "4 characters is the minimum domain name length."
148
174
  end
149
175
 
150
- OpenSession::Attributes.stash "opensecret", "store", store_url.strip
176
+ OpenSession::Attributes.stash "opensecret", "opensecret", "store", store_url.strip
151
177
 
152
178
  ### if( File.exists?( store_url ) && !(File.directory? store_url) )
153
179
  ### abort "The store url path cannot be a file => #{store_url}"
@@ -6,7 +6,7 @@ module OpenSecret
6
6
  require "base64"
7
7
 
8
8
 
9
- # An {OpenSecret::Cipher} is a base class that enables cipher varieties
9
+ # {OpenSecret::Cipher} is a base class that enables cipher varieties
10
10
  # to be plugged and played with minimal effort. This Cipher implements much
11
11
  # of the use case functionality - all extension classes need to do, is
12
12
  # to subclass and implement only the core behaviour that define its identity.
@@ -28,6 +28,7 @@ module OpenSecret
28
28
  # with a powerful symmetric encryption algorithm which could be any one of the
29
29
  # leading ciphers such as TwoFish or the Advanced Encryption Standard (AES).
30
30
  #
31
+ #
31
32
  # == How to Implement a Cipher
32
33
  #
33
34
  # Extend this base class to inherit lots of +unexciting+ functionality
@@ -40,9 +41,8 @@ module OpenSecret
40
41
  # - handles +exceptions+ and +malicious input detection+ and incubation
41
42
  # - +_performs the asymmetric encryption_+ of the cipher's symmetrically encrypted output
42
43
  #
43
- # -------------------------------------
44
- # What Behaviour Must Ciphers Implement
45
- # -------------------------------------
44
+ #
45
+ # == What Behaviour Must Ciphers Implement
46
46
  #
47
47
  # Ciphers bring the cryptographic mathematics and implementation algorithms
48
48
  # to the table. So when at home they must implement
@@ -62,7 +62,7 @@ module OpenSecret
62
62
  # of 8 (or 16) and a common +right pad with spaces+ strategy is employed
63
63
  # as a workaround. opensecret does it diferently.
64
64
  #
65
- # == No Space Padding? | Why Not?
65
+ # == Why isn't Space Padding Used?
66
66
  #
67
67
  # If opensecret padded plaintext (ending in one or more spaces) with
68
68
  # spaces, the decrypt phase (after right stripping spaces) would return
@@ -87,7 +87,7 @@ module OpenSecret
87
87
 
88
88
  # An unusual string that glues together an encryption dictionary and
89
89
  # a chunk of base64 encoded and encrypted ciphertext.
90
- # The string must be unusual enough to ensure it dos not occur within
90
+ # The string must be unusual enough to ensure it does not occur within
91
91
  # the dictionary metadata keys or values.
92
92
  INNER_GLUE_STRING = "\n<-|@| < || opensecret inner crypt material axis || > |@|->\n\n"
93
93
 
@@ -155,7 +155,7 @@ module OpenSecret
155
155
  unified_material = unify_hash_and_text crypted_payload
156
156
  blowfish_cryptor = Blowfish.new
157
157
  outer_crypt_key = OpenSecret::Engineer.strong_key( 128 )
158
- crypted_material = blowfish_cryptor.do_encrypt_with_key unified_material, outer_crypt_key
158
+ crypted_material = blowfish_cryptor.encryptor unified_material, outer_crypt_key
159
159
  crypted_cryptkey = do_asymmetric_encryption public_key_text, outer_crypt_key
160
160
  locked_up_string = unify_text_and_text crypted_cryptkey, crypted_material
161
161
 
@@ -23,45 +23,38 @@ module OpenSecret
23
23
  BLOWFISH_BLOCK_LEN = 8
24
24
 
25
25
 
26
- # This method provides the Blowfish algorithm but we reserve the
27
- # right to enforce upon it an encryption key of our choosing.
26
+ # Encrypt the (plain) text parameter using the symmetric encryption key
27
+ # specified in the second parameter and return the base64 encoded
28
+ # representation of the cipher text.
28
29
  #
29
- # The key length need not be a multiple of 8 - however it is advisable
30
- # to use {Digest::SHA256.digest} to produce a strong 32 character key.
30
+ # Blowfish is a block cipher meaning it needs both the key and the plain
31
+ # text inputted to conform to a divisible block length.
31
32
  #
32
- # == Multiples of 8 | Plain Text Length
33
+ # Don't worry about this block length requirement as this encrption method
34
+ # takes care of it and its sister method {self.decryptor} will also perform
35
+ # the correct reversal activities to give you back the original plain text.
33
36
  #
34
- # Blowfish constrains plain text lengths to multiples of 8 but we
35
- # do NOT walk the common +space padding+ road.
37
+ # {Base64.encode64} facilitates the ciphertext encoding returning text that
38
+ # is safe to write to a file.
36
39
  #
37
- # == No Space Padding? | Why Not?
40
+ # @param plain_text [String]
41
+ # This parameter should be the non-nil text to encrypt using Blowfish.
42
+ # Before encryption the text will be padded using a text string from
43
+ # the {OpenSecret::Cipher::TEXT_PADDER} constant until it results in
44
+ # a string with the required block length.
38
45
  #
39
- # Many ciphers (like Blowfish) constrains plain text lengths to multiples
40
- # of 8 (or 16) and a common +right pad with spaces+ strategy is employed
41
- # as a workaround.
46
+ # @param encryption_key [String]
47
+ # send a long strong unencoded key which does not have to be a multiple of
48
+ # eight even though the algorithm demands it. Before the encryption this key
49
+ # will be passed through a digest using behaviour from {Digest::SHA256.digest}
42
50
  #
43
- # If opensecret padded plaintext (ending in one or more spaces) with
44
- # spaces, the decrypt phase (after right stripping spaces) would return
45
- # plain text string +shorter than the original+.
46
- #
47
- # == So How is Padding Done?
48
- #
49
- # Instead of single space padding - opensecret uses an unlikely 7 character
50
- # delimiter which is repeated until the multiple is reached.
51
- #
52
- # Please see {OpenSecret::Cipher::PLAIN_TEXT_DELIMITER} for the definition
53
- # of the constant delimiter.
54
- #
55
- # == Key Length Error
56
- #
57
- # Short keys receive a <tt>key length too short</tt> error from the
58
- # {OpenSSL::Cipher} class namely {OpenSSL::Cipher::CipherError}.
59
- #
60
- # @param plain_text [String] the text to encrypt using Blowfish
61
- # @param encryption_key [String] strong unencoded (32 character key)
51
+ # This behaviour returns a key whose length is a multiple of eight.
62
52
  #
63
53
  # @return [String] base64 representation of blowfish crypted ciphertext
64
- def do_encrypt_with_key plain_text, encryption_key
54
+ #
55
+ # @raise [OpenSSL::Cipher::CipherError]
56
+ # An (encryption) <tt>key length too short</tt> error is raised for short keys.
57
+ def encryptor plain_text, encryption_key
65
58
 
66
59
  shortkey_msg = "The #{encryption_key.length} character encryption key is too short."
67
60
  raise ArgumentError, shortkey_msg unless encryption_key.length > 8
@@ -73,148 +66,61 @@ module OpenSecret
73
66
 
74
67
  blowfish_encryptor = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).encrypt
75
68
  blowfish_encryptor.key = raw_stretched_key
69
+ encrypted_lines = blowfish_encryptor.update(block_txt) << blowfish_encryptor.final
76
70
 
77
- return Base64.encode64( blowfish_encryptor.update(block_txt) << blowfish_encryptor.final )
71
+ return Base64.encode64( encrypted_lines ).chomp
78
72
 
79
73
  end
80
74
 
81
75
 
82
- =begin
83
- puts "Plain Text => #{sentence}"
84
- puts "Plain Text Length => #{sentence.length}"
85
- puts "Multiple 8 Text => [#{multiple8}]"
86
- puts "Multiple 8 Length => [#{multiple8.length}]"
87
- puts "Encrypted Text Length => #{encrypted_text.length}"
88
- ######### puts "Encrypted Text => #{encrypted_text}"
89
- puts "Base64 Encrypted Text => #{base64_encrypted_text}"
90
-
91
- dbf = OpenSSL::Cipher.new("BF-ECB").decrypt
92
- dbf.key = the_key
93
- debase64_text = Base64.decode64( base64_encrypted_text )
94
- decrypted_text = dbf.update(debase64_text) << dbf.final
95
-
96
- puts "Decrypted Text => #{decrypted_text}"
97
- =end
98
-
99
-
100
-
101
-
102
- # Use the AES 256 bit block cipher and a robust strong random key plus
103
- # initialization vector (IV) to symmetrically encrypt the plain text.
76
+ # Decrypt the cipher text parameter using the symmetric decryption key
77
+ # specified in the second parameter. The cipher text is expected to be
78
+ # base64 encoded as per our sister method {self.encryptor}.
104
79
  #
105
- # Add these key/value pairs to @encryption_dictionary instance map.
80
+ # Its okay to use a bespoke encryptor - just ensure you encode the result
81
+ # and override the padding constant.
106
82
  #
107
- # - <tt>symmetric.cipher</tt> - the algorithm used to encrypt and decrypt
108
- # - <tt>encryption.key</tt> - hex encoded key for encrypting and decrypting
109
- # - <tt>initialize.vector</tt> - the initialization vector known as a IV (four)
83
+ # Blowfish is a block cipher meaning it needs both the key and the plain
84
+ # text inputted to conform to a divisible block length.
110
85
  #
111
- # @param plain_text [String] the plain (or base64 encoded) text to encrypt
112
- # @return [String] the symmetrically encrypted cipher text
113
- def do_symmetric_encryption plain_text
114
-
115
- @cipher_name = "aes-256-cbc"
116
-
117
- crypt_cipher = OpenSSL::Cipher.new @cipher_name
118
- crypt_cipher.encrypt( plain_text )
119
-
120
- @encryption_dictionary = {
121
- @@symmetric_cipher_keyname => @cipher_name,
122
- @@encryption_key_keyname => crypt_cipher.random_key.unpack("H*").first,
123
- @@initialize_vector_keyname => crypt_cipher.random_iv.unpack("H*").first
124
- }
125
-
126
- Base64.encode64( crypt_cipher.update + crypt_cipher.final )
127
-
128
- end
129
-
130
-
131
- # Use the AES 256 bit block cipher together with the encryption key
132
- # and initialization vector (iv) sitting in the encryption_dictionary,
133
- # to symmetrically decrypt the parameter cipher text.
86
+ # Don't worry about this block length requirement as this decrption method
87
+ # takes care of the reversing the activities carried out by {self.encryptor}.
134
88
  #
135
- # == Pre-Condition | Encryption Dictionary
89
+ # @param cipher_text [String]
90
+ # This incoming cipher text should be encoded using {Base64.encode64}
91
+ # and it will be +chomped and stripped upon receipt+ followed by
92
+ # decryption using the Blowfish algorithm.
136
93
  #
137
- # This method requires the <tt>@encryption_dictionary</tt> instance
138
- # variable to have been set and to contain (amongst others)
94
+ # @param decryption_key [String]
95
+ # Send the same key that was used during the encryption phase. The encryption
96
+ # phase passed the key through the {Digest::SHA256.digest} digest so here
97
+ # the decryption does the exact same thing.
139
98
  #
140
- # - the <tt>encryption.key</tt> - hex encoded key for encrypting and decrypting
141
- # - and <tt>initialize.vector</tt> - the initialization vector known as a IV (four)
99
+ # The digest processing guarantees a symmetric key whose length conforms to
100
+ # the multiple of eight block length requirement.
142
101
  #
143
- # @param cipher_text [String] the base64 encoded cipher text to decrypt
144
- # @return [String] decrypted plain text from symmetric key and cipher text
145
- def do_symmetric_decryption cipher_text
146
-
147
- abort "Implement AES 256 decryption in aes-256"
102
+ # @return [String]
103
+ # After decoding and decryption the plain text string will still be padded,
104
+ # +but not with spaces+. The unlikely to occur padding string constant used
105
+ # is the {OpenSecret::Cipher::TEXT_PADDER}.
106
+ #
107
+ # If the plaintext ended with spaces these would be preserved. After padder
108
+ # removal any trailing spaces will be preserved in the returned plain text.
109
+ #
110
+ def decryptor cipher_text, decryption_key
148
111
 
149
- end
112
+ decoded_text = Base64.decode64(cipher_text.chomp.strip)
113
+ digested_key = Digest::SHA256.digest decryption_key
150
114
 
115
+ decrypt_tool = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).decrypt
116
+ decrypt_tool.key = digested_key
151
117
 
118
+ padded_plaintxt = decrypt_tool.update(decoded_text) << decrypt_tool.final
119
+ pad_begin_index = padded_plaintxt.index OpenSecret::Cipher::TEXT_PADDER
120
+ return padded_plaintxt if pad_begin_index.nil?
121
+ return padded_plaintxt[ 0 .. (pad_begin_index-1) ]
152
122
 
153
- =begin
154
- encode_cipher = OpenSSL::Cipher.new('aes-256-cbc')
155
- encode_cipher.encrypt # We are encrypting
156
- key = encode_cipher.random_key
157
- iv = encode_cipher.random_iv
158
- hex_key = key.unpack("H*").first
159
- hex_iv = iv.unpack("H*").first
160
-
161
- line1 = "1>> This is secret number one over here with at @ and squiggle~ and round brakets().\n"
162
- line2 = "2>> secret number two with colon and semi :; angular <> qmarks ??.\n"
163
- line3 = "3>> secret number 3 fwd slash / and backslash twice \\ and pipe || and excla !!\n"
164
- line4 = "4>> secret 4 with pound ££ dollar $$ percent %% hat ^^ ampr && stars **\n"
165
- line5 = "5>> secret 5 with hyphens - and underscore __ and plus ++ and equal == and sqBs [[]].\n"
166
- line6 = "6>> secret 6 with double quote \"from here to here\" and \' single quotes\'.\n"
167
- line7 = "7>> secret 7 with periods .... and hashes #####\n"
168
-
169
- crypt_text = ""
170
- crypt_text += encode_cipher.update line1
171
- crypt_text += encode_cipher.update line2
172
- crypt_text += encode_cipher.update line3
173
- crypt_text += encode_cipher.update line4
174
- crypt_text += encode_cipher.update line5
175
- crypt_text += encode_cipher.update line6
176
- crypt_text += encode_cipher.update line7
177
- crypt_text += encode_cipher.final
178
- coded_crypt_text = Base64.encode64(crypt_text)
179
-
180
- puts ""
181
- puts "The key is #{hex_key}"
182
- puts "The IV is #{hex_iv}"
183
- puts "========================"
184
- puts "The Cipher Text is Below"
185
- puts "========================"
186
- puts coded_crypt_text
187
- puts "========================"
188
- puts crypt_text
189
- puts "========================"
190
- puts "========================"
191
- puts "========================"
192
- puts line1 + line2 + line3 + line4 + line5 + line6 + line7
193
- puts "========================"
194
- puts "========================"
195
- puts "========================"
196
- puts ""
197
- puts ""
198
-
199
- unencoded_crypt_text = Base64.decode64(coded_crypt_text)
200
- decode_cipher = OpenSSL::Cipher.new('aes-256-cbc')
201
-
202
- decode_cipher.decrypt
203
- decode_cipher.key = [hex_key].pack("H*")
204
- decode_cipher.iv = [hex_iv].pack("H*")
205
- first_part = decode_cipher.update( Base64.decode64(coded_crypt_text) )
206
- second_part = ""
207
- second_part << decode_cipher.final
208
-
209
- puts "========================"
210
- puts "Decrypted Text is Below"
211
- puts "========================"
212
- puts first_part
213
- puts "========================"
214
- puts second_part
215
- puts "========================"
216
- puts ""
217
- =end
123
+ end
218
124
 
219
125
 
220
126
  end