opensecret 0.0.941 → 0.0.946

Sign up to get free protection for your applications and to get access to all the features.
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