opensecret 0.0.941 → 0.0.946

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 435d9f265cc382a9089c052a748983ee1218c0af
4
- data.tar.gz: 6f7015d873d0b4856c587b8edfcfe25688522106
3
+ metadata.gz: f03e1b5d062560593f42736baf5a2af7794a4c0b
4
+ data.tar.gz: ed65d8e10bd446f1413d9e0473b7291ec01f34a6
5
5
  SHA512:
6
- metadata.gz: 3218882929dfda77e99a9fcf164141cfaa1f6b114fe810100db352d4b16f5e02dd4c9d3dea9112742094c02cab8bc6aed2e322c931611e7bad2ffc2ca398898a
7
- data.tar.gz: ce95ccdee60463940cd67a99faa028afc64d4cdddd1c9b9663d4dab01510670330ea3cc222d1501be275c820098f44acf5fee9daccc88a58b940d17dd37d5586
6
+ metadata.gz: 57989150d89ee5cc20d5950bd008b5bc97f4b23455dc690b66f791d1b3d1330a7550ce888715c73abf4bf43dd4ce80e409202c5393a7b32cc1bc41d75d97e047
7
+ data.tar.gz: 842b02b7f3a2fbf99fdd3c9d4acbeeabcf16bed137894cf8d2ad1cc4aed54f6d39975c2d16714e3d8e16eb62bc9271d2a2a60bee2d6bd12c954bfeef0b71cb3b
@@ -2,45 +2,33 @@
2
2
 
3
3
  module OpenSecret
4
4
 
5
- # This class will be refactored into an interface implemented by a set
6
- # of plugins that will capture sensitive information from users from an
7
- # Ubuntu, Windows, RHEL, CoreOS, iOS or CentOS command line interface.
5
+ # This class knows how to amalgamate passwords, keys and string data in
6
+ # a manner that is the cryptographical equivalent of synergy.
8
7
  #
9
- # An equivalent REST API will also be available for bringing in sensitive
10
- # information in the most secure (but simple) manner.
11
- class Collect
8
+ # The amalgamated keys are synergially (cryptographically) greater than
9
+ # the sum of their parts.
10
+ class Amalgam
12
11
 
13
- # Register two fundamental opensecret crypt pointers
12
+ # Amalgamate the two parameter passwords in a manner that is the
13
+ # cryptographical equivalent of synergy. The amalgamated keys are
14
+ # synergially greater than the sum of their parts.
14
15
  #
15
- # - an opensecret domain like » **lecturers@harvard**
16
- # - the url to a backend store like Git, S3 or an SSH accessible drive.
16
+ # -- Get a viable machine password taking into account the human
17
+ # -- password length and the specified mix_ratio.
17
18
  #
18
- # The domain will be extended to cover verified internet domains.
19
- # They will also latch onto LDAP domains so when admins add, revoke
20
- # or remove users, their opensecret access is adjusted accordingly.
21
19
  #
22
- # @param domain [String] the DOMAIN eg lecturers@harvard for your family or work group.
23
- # @param store_url [String] the STORE_URL for connecting to the backend storage service
20
+ # @param human_password [String] the password originating from a human
21
+ # @param machine_key [String] a machine engineered ascii password (key)
22
+ # @mixparam machine_key [String] a machine engineered ascii password (key)
24
23
  #
25
- def self.register_domain domain, store_url
26
-
27
- # -> read config file map
28
- # -> create new domain in map
29
- # -> add type and store url to map
30
- # -> backup configuration
31
- # -> overwrite the ini config file
32
- puts "hello i am registering this super domain #{domain} at #{store_url}"
33
-
34
- end
35
-
36
-
37
- # --
38
- # -- Get a viable machine password taking into account the human
39
- # -- password length and the specified mix_ratio.
40
- # --
41
- # -- machine password length = human password length * mix_ratio - 1
42
- # --
43
- def self.get_amalgam_password human_password, machine_password, mix_ratio
24
+ # @return [String] the union of the two parameter passwords
25
+ #
26
+ # @raise [ArgumentError] when the size of the two passwords and the
27
+ # mix ratio do not conform to the constraint imposed by the below
28
+ # equation which must hold true.
29
+ # <tt>machine password length = human password length * mix_ratio - 1</tt>
30
+ #
31
+ def self.passwords human_password, machine_password, mix_ratio
44
32
 
45
33
  size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
46
34
  lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
@@ -70,132 +58,7 @@ module OpenSecret
70
58
  end
71
59
 
72
60
 
73
- # --
74
- # -- Get a viable machine password taking into account the human
75
- # -- password length and the specified mix_ratio.
76
- # --
77
- # -- machine password length = human password length * mix_ratio - 1
78
- # --
79
- def self.get_machine_password human_password_length, mix_ratio
80
-
81
- machine_raw_secret = engineer_password( human_password_length * ( mix_ratio + 1) )
82
- return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
83
-
84
- end
85
-
86
-
87
- # --
88
- # -- Collect a password from the user with a minimum length
89
- # -- specified in the parameter.
90
- # --
91
- # -- An exception is raised if the minimum length is not at
92
- # -- least 8 characters.
93
- # --
94
- def self.collect_secret minimum_size, prompt_1, prompt_2
95
-
96
- assert_min_size minimum_size
97
-
98
- sleep(1)
99
- puts "\n#{prompt_1} : "
100
- first_secret = STDIN.noecho(&:gets).chomp
101
-
102
- assert_input_text_size first_secret.length, minimum_size
103
-
104
- sleep(1)
105
- puts "\n#{prompt_2} : "
106
- check_secret = STDIN.noecho(&:gets).chomp
107
-
108
- assert_same_size_text first_secret, check_secret
109
-
110
- return first_secret
111
-
112
- end
113
-
114
-
115
- # --
116
- # -- Engineer a raw password that is similar (approximate) in
117
- # -- length to the integer parameter.
118
- # --
119
- def self.engineer_password approx_length
120
-
121
- non_alphanum = SecureRandom.urlsafe_base64(approx_length);
122
- return non_alphanum.delete("-_")
123
-
124
- end
125
-
126
-
127
- # --
128
- # -- Raise an exception if asked to collect text that is less
129
- # -- than 3 characters in length.
130
- # --
131
- def self.assert_min_size minimum_size
132
-
133
- min_length_msg = "\n\nCrypts with 2 (or less) characters open up exploitable holes.\n\n"
134
- raise ArgumentError.new min_length_msg if minimum_size < 3
135
-
136
- end
137
-
138
-
139
- # --
140
- # -- Output an error message and then exit if the entered input
141
- # -- text size does not meet the minimum requirements.
142
- # --
143
- def self.assert_input_text_size input_size, minimum_size
144
-
145
- if( input_size < minimum_size )
146
-
147
- puts
148
- puts "Input is too short. Please enter at least #{minimum_size} characters."
149
- puts
150
-
151
- exit
152
-
153
- end
154
-
155
- end
156
-
157
-
158
- # --
159
- # -- Assert that the text entered the second time is exactly (case sensitive)
160
- # -- the same as the text entered the first time.
161
- # --
162
- def self.assert_same_size_text first_text, second_text
163
-
164
- unless( first_text.eql? second_text )
165
-
166
- puts
167
- puts "Those two bits of text are not the same (in my book)!"
168
- puts
169
-
170
- exit
171
-
172
- end
173
-
174
- end
175
-
176
-
177
- # --
178
- # -- Print out the machine password that is to be kept as an environment variable
179
- # -- on any workstation used for material decryption.
180
- # --
181
- # -- Remember that neither the human nor machine passwords are required for the
182
- # -- encryption phase. That is the beauty of assymetric cryptography - you don't
183
- # -- need a private key to encrypt - just the end user's public key.
184
- # --
185
- def self.print_secret_env_var env_var_name, env_var_value
186
-
187
- machine_to_env_txt = "sudo echo \"#{env_var_name}=#{env_var_value}\" >> /etc/environment"
188
-
189
- puts
190
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
191
- puts "@@@ Add as environment variable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
192
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
193
- puts machine_to_env_txt
194
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
195
- puts
196
-
197
- end
198
-
199
61
  end
200
62
 
63
+
201
64
  end
@@ -0,0 +1,85 @@
1
+
2
+
3
+
4
+
5
+ class BF < Struct.new(:key, :pad_with_spaces)
6
+ def encrypt(str)
7
+ cipher = OpenSSL::Cipher.new('bf-ecb').encrypt
8
+ if pad_with_spaces
9
+ str += " " until str.bytesize % 8 == 0
10
+ cipher.padding = 0
11
+ end
12
+ cipher.key = key
13
+ binary_data = cipher.update(str) << cipher.final
14
+ hex_encoded = binary_data.unpack('H*').first
15
+ end
16
+
17
+ def decrypt(hex_encoded)
18
+ cipher = OpenSSL::Cipher.new('bf-ecb').decrypt
19
+ cipher.padding = 0 if pad_with_spaces
20
+ cipher.key = key
21
+ binary_data = [hex_encoded].pack('H*')
22
+ str = cipher.update(binary_data) << cipher.final
23
+ str.force_encoding(Encoding::UTF_8)
24
+ str
25
+ end
26
+ end
27
+
28
+ =begin
29
+ # Choose the encryption key. Its length must be a multiple of 8 and no longer than 56
30
+ bf = BF.new("x"*56, true)
31
+ sentence = ARGV[0] || "foo bar foo bar foo bar foo bar foo bar foo bar baz"
32
+ encrypted = bf.encrypt(sentence)
33
+ puts encrypted.length
34
+ puts sentence.inspect
35
+ puts "Encrypt: #{encrypted}"
36
+ puts "Decoded: #{bf.decrypt encrypted}"
37
+ =end
38
+
39
+
40
+
41
+ =begin
42
+ require 'openssl'
43
+ module Blowfish
44
+ def self.cipher(mode, key, data)
45
+ cipher = OpenSSL::Cipher::Cipher.new('bf-cbc').send(mode)
46
+ cipher.key = Digest::SHA256.digest(key)
47
+ cipher.update(data) << cipher.final
48
+ end
49
+
50
+ def self.encrypt(key, data)
51
+ cipher(:encrypt, key, data)
52
+ end
53
+
54
+ def self.decrypt(key, text)
55
+ cipher(:decrypt, key, text)
56
+ end
57
+ end
58
+
59
+ if $0 == __FILE__
60
+ p "text" == Blowfish.decrypt("key", Blowfish.encrypt("key", "text"))
61
+ end
62
+ =end
63
+
64
+ =begin
65
+ module Blowfish
66
+ def self.cipher(mode, key, data)
67
+ cipher = OpenSSL::Cipher::Cipher.new('bf-cbc').send(mode)
68
+ cipher.key = Digest::SHA256.digest(key)
69
+ cipher.update(data) << cipher.final
70
+ end
71
+
72
+ def self.encrypt(key, data)
73
+ cipher(:encrypt, key, data)
74
+ end
75
+
76
+ def self.decrypt(key, text)
77
+ cipher(:decrypt, key, text)
78
+ end
79
+ end
80
+
81
+ if $0 == __FILE__
82
+ p "text" == Blowfish.decrypt("key", Blowfish.encrypt("key", "text"))
83
+ end
84
+
85
+ =end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module OpenSecret
4
4
 
5
+ require 'io/console'
5
6
 
6
7
  # This class will be refactored into an interface implemented by a set
7
8
  # of plugins that will capture sensitive information from users from an
@@ -2,73 +2,15 @@
2
2
 
3
3
  module OpenSecret
4
4
 
5
+ require 'securerandom'
6
+
5
7
  # This class will be refactored into an interface implemented by a set
6
8
  # of plugins that will capture sensitive information from users from an
7
9
  # Ubuntu, Windows, RHEL, CoreOS, iOS or CentOS command line interface.
8
10
  #
9
11
  # An equivalent REST API will also be available for bringing in sensitive
10
12
  # information in the most secure (but simple) manner.
11
- class Collect
12
-
13
- # Register two fundamental opensecret crypt pointers
14
- #
15
- # - an opensecret domain like &raquo; **lecturers@harvard**
16
- # - the url to a backend store like Git, S3 or an SSH accessible drive.
17
- #
18
- # The domain will be extended to cover verified internet domains.
19
- # They will also latch onto LDAP domains so when admins add, revoke
20
- # or remove users, their opensecret access is adjusted accordingly.
21
- #
22
- # @param domain [String] the DOMAIN eg lecturers@harvard for your family or work group.
23
- # @param store_url [String] the STORE_URL for connecting to the backend storage service
24
- #
25
- def self.register_domain domain, store_url
26
-
27
- # -> read config file map
28
- # -> create new domain in map
29
- # -> add type and store url to map
30
- # -> backup configuration
31
- # -> overwrite the ini config file
32
- puts "hello i am registering this super domain #{domain} at #{store_url}"
33
-
34
- end
35
-
36
-
37
- # --
38
- # -- Get a viable machine password taking into account the human
39
- # -- password length and the specified mix_ratio.
40
- # --
41
- # -- machine password length = human password length * mix_ratio - 1
42
- # --
43
- def self.get_amalgam_password human_password, machine_password, mix_ratio
44
-
45
- size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
46
- lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
47
- raise ArgumentError.new size_error_msg unless lengths_are_perfect
48
-
49
- machine_passwd_chunk = 0
50
- amalgam_passwd_index = 0
51
- amalgamated_password = ""
52
-
53
- human_password.each_char do |passwd_char|
54
-
55
- amalgamated_password[amalgam_passwd_index] = passwd_char
56
- amalgam_passwd_index += 1
57
-
58
- for i in 0..(mix_ratio-1) do
59
- machine_pass_index = machine_passwd_chunk * mix_ratio + i
60
- amalgamated_password[amalgam_passwd_index] = machine_password[machine_pass_index]
61
- amalgam_passwd_index += 1
62
- end
63
-
64
- machine_passwd_chunk += 1
65
-
66
- end
67
-
68
- return amalgamated_password
69
-
70
- end
71
-
13
+ class Engineer
72
14
 
73
15
  # --
74
16
  # -- Get a viable machine password taking into account the human
@@ -76,7 +18,7 @@ module OpenSecret
76
18
  # --
77
19
  # -- machine password length = human password length * mix_ratio - 1
78
20
  # --
79
- def self.get_machine_password human_password_length, mix_ratio
21
+ def self.machine_key human_password_length, mix_ratio
80
22
 
81
23
  machine_raw_secret = engineer_password( human_password_length * ( mix_ratio + 1) )
82
24
  return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
@@ -84,34 +26,6 @@ module OpenSecret
84
26
  end
85
27
 
86
28
 
87
- # --
88
- # -- Collect a password from the user with a minimum length
89
- # -- specified in the parameter.
90
- # --
91
- # -- An exception is raised if the minimum length is not at
92
- # -- least 8 characters.
93
- # --
94
- def self.collect_secret minimum_size, prompt_1, prompt_2
95
-
96
- assert_min_size minimum_size
97
-
98
- sleep(1)
99
- puts "\n#{prompt_1} : "
100
- first_secret = STDIN.noecho(&:gets).chomp
101
-
102
- assert_input_text_size first_secret.length, minimum_size
103
-
104
- sleep(1)
105
- puts "\n#{prompt_2} : "
106
- check_secret = STDIN.noecho(&:gets).chomp
107
-
108
- assert_same_size_text first_secret, check_secret
109
-
110
- return first_secret
111
-
112
- end
113
-
114
-
115
29
  # --
116
30
  # -- Engineer a raw password that is similar (approximate) in
117
31
  # -- length to the integer parameter.
@@ -124,78 +38,44 @@ module OpenSecret
124
38
  end
125
39
 
126
40
 
127
- # --
128
- # -- Raise an exception if asked to collect text that is less
129
- # -- than 3 characters in length.
130
- # --
131
- def self.assert_min_size minimum_size
132
-
133
- min_length_msg = "\n\nCrypts with 2 (or less) characters open up exploitable holes.\n\n"
134
- raise ArgumentError.new min_length_msg if minimum_size < 3
135
-
136
- end
137
-
138
41
 
139
42
  # --
140
- # -- Output an error message and then exit if the entered input
141
- # -- text size does not meet the minimum requirements.
142
- # --
143
- def self.assert_input_text_size input_size, minimum_size
144
-
145
- if( input_size < minimum_size )
146
-
147
- puts
148
- puts "Input is too short. Please enter at least #{minimum_size} characters."
149
- puts
150
-
151
- exit
152
-
153
- end
154
-
155
- end
156
-
157
-
43
+ # -- Get a viable machine password taking into account the human
44
+ # -- password length and the specified mix_ratio.
158
45
  # --
159
- # -- Assert that the text entered the second time is exactly (case sensitive)
160
- # -- the same as the text entered the first time.
46
+ # -- machine password length = human password length * mix_ratio - 1
161
47
  # --
162
- def self.assert_same_size_text first_text, second_text
163
-
164
- unless( first_text.eql? second_text )
48
+ def self.get_amalgam_password human_password, machine_password, mix_ratio
165
49
 
166
- puts
167
- puts "Those two bits of text are not the same (in my book)!"
168
- puts
50
+ size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
51
+ lengths_are_perfect = human_password.length * mix_ratio == machine_password.length
52
+ raise ArgumentError.new size_error_msg unless lengths_are_perfect
169
53
 
170
- exit
54
+ machine_passwd_chunk = 0
55
+ amalgam_passwd_index = 0
56
+ amalgamated_password = ""
171
57
 
172
- end
58
+ human_password.each_char do |passwd_char|
173
59
 
174
- end
60
+ amalgamated_password[amalgam_passwd_index] = passwd_char
61
+ amalgam_passwd_index += 1
175
62
 
63
+ for i in 0..(mix_ratio-1) do
64
+ machine_pass_index = machine_passwd_chunk * mix_ratio + i
65
+ amalgamated_password[amalgam_passwd_index] = machine_password[machine_pass_index]
66
+ amalgam_passwd_index += 1
67
+ end
176
68
 
177
- # --
178
- # -- Print out the machine password that is to be kept as an environment variable
179
- # -- on any workstation used for material decryption.
180
- # --
181
- # -- Remember that neither the human nor machine passwords are required for the
182
- # -- encryption phase. That is the beauty of assymetric cryptography - you don't
183
- # -- need a private key to encrypt - just the end user's public key.
184
- # --
185
- def self.print_secret_env_var env_var_name, env_var_value
69
+ machine_passwd_chunk += 1
186
70
 
187
- machine_to_env_txt = "sudo echo \"#{env_var_name}=#{env_var_value}\" >> /etc/environment"
71
+ end
188
72
 
189
- puts
190
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
191
- puts "@@@ Add as environment variable @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
192
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
193
- puts machine_to_env_txt
194
- puts "@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
195
- puts
73
+ return amalgamated_password
196
74
 
197
75
  end
198
76
 
77
+
199
78
  end
200
79
 
80
+
201
81
  end