c7decrypt 0.2.6 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4c3a9b400ae6f576e417c8feab081a032749f22
4
- data.tar.gz: 799c99315d7b7604c26b07d6707a221ee244f21f
3
+ metadata.gz: f70de5c1f93bf9ad137dea9dd3fa33db2a793fa0
4
+ data.tar.gz: 5a8f766cf0de4464adf4c87f09e8148b3d8326ec
5
5
  SHA512:
6
- metadata.gz: 8d997d254c5ae60d1ead6a468abbb3a4ba7f4dc07ccc9cd8f2d86443377fc82d10315d2879be2cca2e95a5ac11f0f776fe140abeab7e4d9f5e5a72a32a153482
7
- data.tar.gz: a490e626d751ba8bdd94fe925d39e2d548e48624a233b08da9d255056697bd0e3808c75aee380ac94bd286f197fe534e492e4c6d1d71270f161dc8529d8f4801
6
+ metadata.gz: c55ffa4cb4fa17dafd2c8e97758f057e92b3b65101c53b7c2eec05803792e5e5b32720d195c1633b4a74273a66fcf7284d9c00e8734d8210d0d7e958e6ee5543
7
+ data.tar.gz: 3de9b21375709c209da4fd865c33984c3700cee54df3d95d9be6c265c16c6992b6a6110f6b2f85a154c5aadd004192adcd71f520f4e59e196fd28c647f108b78
data/README.md CHANGED
@@ -47,7 +47,7 @@ require 'c7decrypt'
47
47
  Decrypt A Single Encrypted Password
48
48
 
49
49
  ```ruby
50
- >> C7Decrypt.decrypt("060506324F41")
50
+ >> C7Decrypt::Type7.decrypt("060506324F41")
51
51
  => "cisco"
52
52
  ```
53
53
 
@@ -56,28 +56,28 @@ Decrypt Array of Encrypted Passwords
56
56
  ```ruby
57
57
  >> encrypted_hashes = ["060506324F41", "0822455D0A16"]
58
58
  => ["060506324F41", "0822455D0A16"]
59
- >> C7Decrypt.decrypt_array(encrypted_hashes)
59
+ >> C7Decrypt::Type7.decrypt_array(encrypted_hashes)
60
60
  => ["cisco", "cisco"]
61
61
  ```
62
62
 
63
63
  Decrypt Encrypted Passwords from Config
64
64
 
65
65
  ```ruby
66
- >> C7Decrypt.decrypt_config("cisco_config.txt")
66
+ >> C7Decrypt::Type7.decrypt_config("cisco_config.txt")
67
67
  => ["cisco", "Password1", "admin"]
68
68
  ```
69
69
 
70
70
  Encrypt A Single Plaintext Password
71
71
 
72
72
  ```ruby
73
- >> C7Decrypt.encrypt("cisco")
73
+ >> C7Decrypt::Type7.encrypt("cisco")
74
74
  => "02050D480809"
75
75
  ```
76
76
 
77
77
  Encrypt A Single Plaintext Password w/ Explicit Seed
78
78
 
79
79
  ```ruby
80
- >> C7Decrypt.encrypt("cisco", 6)
80
+ >> C7Decrypt::Type7.encrypt("cisco", 6)
81
81
  => "060506324F41"
82
82
  ```
83
83
 
@@ -86,7 +86,7 @@ Encrypt An Array of Plaintext Passwords
86
86
  ```ruby
87
87
  >> passwords = ["cisco", "password"]
88
88
  => ["cisco", "password"]
89
- >> C7Decrypt.encrypt_array(passwords)
89
+ >> C7Decrypt::Type7.encrypt_array(passwords)
90
90
  => ["02050D480809", "021605481811003348"]
91
91
  ```
92
92
 
data/bin/c7decrypt CHANGED
@@ -48,11 +48,11 @@ if options.string.nil? &&
48
48
  end
49
49
 
50
50
  if options.string
51
- puts C7Decrypt.decrypt(options.string)
51
+ puts C7Decrypt::Type7.decrypt(options.string)
52
52
  end
53
53
 
54
54
  if options.file &&
55
55
  File.exists?(options.file)
56
56
 
57
- C7Decrypt.decrypt_config(options.file).each {|pw| puts pw }
57
+ C7Decrypt::Type7.decrypt_config(options.file).each {|pw| puts pw }
58
58
  end
data/c7decrypt.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.homepage = 'http://rubygems.org/gems/c7decrypt'
28
28
 
29
29
  s.add_development_dependency('fuzzbert')
30
- s.add_development_dependency('rspec', '~> 2.14.1')
30
+ s.add_development_dependency('rspec', '~> 3.0.0')
31
+ s.add_development_dependency('rspec-its')
31
32
  s.add_development_dependency('rake')
32
33
  end
data/lib/c7decrypt.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  require 'c7decrypt/version'
2
- require 'c7decrypt/c7decrypt'
2
+ require 'c7decrypt/type7'
@@ -0,0 +1,188 @@
1
+ module C7Decrypt
2
+ module Type7
3
+
4
+ module Constants
5
+ # Vigenere translation table (these are our key values for decryption)
6
+ VT_TABLE = [
7
+ 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e,
8
+ 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44,
9
+ 0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39,
10
+ 0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76, 0x39, 0x38, 0x37, 0x33,
11
+ 0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37
12
+ ]
13
+
14
+ # Regexes for extracting hashes from configs
15
+ TYPE_7_REGEXES = [
16
+ /enable password 7 ([A-Z0-9]+)/,
17
+ /username [A-Z0-9]+ password 7 ([A-Z0-9]+)/,
18
+ /password 7 ([A-Z0-9]+)/
19
+ ]
20
+ end
21
+
22
+ class InvalidFirstCharacter < StandardError
23
+ end
24
+
25
+ class InvalidCharacter < StandardError
26
+ end
27
+
28
+ class OddNumberOfCharacters < StandardError
29
+ end
30
+
31
+ class InvalidEncryptionSeed < StandardError
32
+ end
33
+
34
+ # The Decryption Method for Cisco Type-7 Encrypted Strings
35
+ # @param [String] the Cisco Type-7 Encrypted String
36
+ # @raise [InvalidFirstCharacter,
37
+ # InvalidCharacter,
38
+ # OddNumberOfCharacters]
39
+ # @return [String] the Decrypted String
40
+ def self.decrypt(e_text)
41
+ check_type_7_errors(e_text)
42
+
43
+ d_text = ""
44
+ seed = nil
45
+
46
+ e_text.scan(/../).each_with_index do |char,i|
47
+ if i == 0
48
+ seed = char.to_i - 1
49
+ else
50
+ d_text += decrypt_char(char, i, seed)
51
+ end
52
+ end
53
+
54
+ return d_text
55
+ end
56
+
57
+ # The Encryption Method for Cisco Type-7 Encrypted Strings
58
+ # @param [String] the plaintext password
59
+ # @param [String] the seed for the encryption used
60
+ # @raise [InvalidEncryptionSeed,
61
+ # InvalidFirstCharacter,
62
+ # InvalidCharacter,
63
+ # OddNumberOfCharacters]
64
+ # @return [String] the encrypted password
65
+ def self.encrypt(d_text, seed = 2)
66
+ check_seed(seed)
67
+
68
+ e_text = sprintf("%02d", seed)
69
+
70
+ d_text.each_char.each_with_index do |d_char,i|
71
+ e_text += encrypt_char(d_char, i, seed)
72
+ end
73
+
74
+ check_type_7_errors(e_text)
75
+
76
+ return e_text
77
+ end
78
+
79
+ # The method for encrypting a single character
80
+ # @param [String] the plain text char
81
+ # @param [FixNum] the index of the char in plaintext string
82
+ # @param [FixNum] the seed used in the encryption process
83
+ # @return [String] the string of the encrypted char
84
+ def self.encrypt_char(char, i, seed)
85
+ sprintf("%02X", char.unpack('C')[0] ^ Constants::VT_TABLE[(i + seed) % 53])
86
+ end
87
+
88
+ # The method for decrypting a single character
89
+ # @param [String] the encrypted char
90
+ # @param [Integer] the index of the char pair in encrypted string
91
+ # @param [Integer] the seed used in the decryption process
92
+ # @return [String] the string of the decrypted char
93
+ def self.decrypt_char(char, i, seed)
94
+ (char.hex^Constants::VT_TABLE[(i + seed) % 53]).chr
95
+ end
96
+
97
+ # A helper method to decrypt an arracy of Cisco Type-7 Encrypted Strings
98
+ # @param [Array>String] an array of Cisco Type-7 Encrypted Strings
99
+ # @raise [InvalidFirstCharacter,
100
+ # InvalidCharacter,
101
+ # OddNumberOfCharacters]
102
+ # @return [Array>String] an array of Decrypted Strings
103
+ def self.decrypt_array(pw_array)
104
+ pw_array.collect {|pw| decrypt(pw)}
105
+ end
106
+
107
+ # A helper method to encrypt an arracy of passwords
108
+ # @param [Array>String] an array of plain-text passwords
109
+ # @raise [InvalidEncryptionSeed,
110
+ # InvalidFirstCharacter,
111
+ # InvalidCharacter,
112
+ # OddNumberOfCharacters]
113
+ # @return [Array>String] an array of encrypted passwords
114
+ def self.encrypt_array(pt_array, seed = 2)
115
+ pt_array.collect {|pw| encrypt(pw, seed)}
116
+ end
117
+
118
+ # This method scans a raw config file for type 7 passwords and
119
+ # decrypts them
120
+ # @param [String] a string of the config file path that contains
121
+ # Cisco Type-7 Encrypted Strings
122
+ # @raise [InvalidFirstCharacter,
123
+ # InvalidCharacter,
124
+ # OddNumberOfCharacters]
125
+ # @return [Array>String] an array of Decrypted Strings
126
+ def self.decrypt_config(file)
127
+ f = File.open(file, 'r').to_a
128
+ decrypt_array(f.collect {|line| type_7_matches(line)}.flatten)
129
+ end
130
+
131
+ # This method scans a config line for encrypted type-7 passwords and
132
+ # returns an array of results
133
+ # @param [String] a line with potential encrypted type-7 passwords
134
+ # @return [Array>String] an array of Cisco type-7 encrypted Strings
135
+ def self.type_7_matches(string)
136
+ Constants::TYPE_7_REGEXES.collect {|regex| string.scan(regex)}.flatten.uniq
137
+ end
138
+
139
+ # This method determines if an encrypted hash is corrupted/invalid
140
+ # and throw a specific exeception
141
+ # @param [String] the Cisco Type-7 Encrypted String
142
+ # @raise [InvalidFirstCharacter, InvalidCharacter, OddNumberOfCharacters]
143
+ # @return [Nil]
144
+ def self.check_type_7_errors(e_text)
145
+
146
+ valid_first_chars = (0..15).to_a.collect {|c| sprintf("%02d", c)}
147
+ first_char = e_text[0,2]
148
+
149
+ # Check for an invalid first character in the has
150
+ unless valid_first_chars.include? first_char
151
+ raise InvalidFirstCharacter,
152
+ "'#{e_text}' hash contains an invalid first chracter (only '00' - '15' allowed)"
153
+ end
154
+
155
+ # Check for an invalid character in the hash
156
+ unless e_text.match(/^[A-Z0-9]+$/)
157
+ raise InvalidCharacter,
158
+ "'#{e_text}' hash contains an invalid character (only upper-alpha numeric allowed)"
159
+ end
160
+
161
+ # Check for an odd number of characters in the hash
162
+ unless e_text.size % 2 == 0
163
+ raise OddNumberOfCharacters,
164
+ "'#{e_text}' hash contains odd length of chars (only even number of chars allowed)"
165
+ end
166
+
167
+ return nil
168
+
169
+ end
170
+
171
+ # This method determines if an encryption seed is valid or not
172
+ # and throw a specific exeception
173
+ # @param [FixNum] the seed used in the encryption process
174
+ # @raise [InvalidEncryptionSeed]
175
+ # @return [Nil]
176
+ def self.check_seed(seed)
177
+ if seed < 0 ||
178
+ seed > 15
179
+
180
+ raise InvalidEncryptionSeed,
181
+ "'#{seed.to_s}' seed is not a valid seed (only 0 - 15 allowed)"
182
+ end
183
+
184
+ return nil
185
+ end
186
+
187
+ end
188
+ end
@@ -1,3 +1,3 @@
1
1
  module C7Decrypt
2
- VERSION = '0.2.6'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'c7decrypt'
2
+ require 'rspec/its'
2
3
 
3
- describe C7Decrypt do
4
+ describe C7Decrypt::Type7 do
4
5
 
5
6
  before(:each) do
6
7
  @known_values = [
@@ -20,7 +21,7 @@ describe C7Decrypt do
20
21
  context "when decrypting single Cisco Type-7 hash using longhand" do
21
22
  before(:each) do
22
23
  @encrypted_hash = "060506324F41"
23
- @decrypted_hash = C7Decrypt.decrypt(@encrypted_hash)
24
+ @decrypted_hash = C7Decrypt::Type7.decrypt(@encrypted_hash)
24
25
  end
25
26
 
26
27
  subject{@decrypted_hash}
@@ -34,7 +35,7 @@ describe C7Decrypt do
34
35
  "060506324F41",
35
36
  "0822455D0A16"
36
37
  ]
37
- @decrypted_hashes = C7Decrypt.decrypt_array(@encrypted_hashes)
38
+ @decrypted_hashes = C7Decrypt::Type7.decrypt_array(@encrypted_hashes)
38
39
  end
39
40
 
40
41
  subject{@decrypted_hashes}
@@ -47,7 +48,7 @@ describe C7Decrypt do
47
48
  context "when decrypting Cisco Type-7 hashes from a config" do
48
49
  before(:each) do
49
50
  @config_file = "./spec/example_configs/simple_canned_example.txt"
50
- @decrypted_hashes = C7Decrypt.decrypt_config(@config_file)
51
+ @decrypted_hashes = C7Decrypt::Type7.decrypt_config(@config_file)
51
52
  end
52
53
 
53
54
  subject{@decrypted_hashes}
@@ -64,7 +65,7 @@ describe C7Decrypt do
64
65
 
65
66
  context "when decrypting known Cisco Type-7 known value matches" do
66
67
  before(:each) do
67
- @decrypted_hashes = C7Decrypt.decrypt_array(
68
+ @decrypted_hashes = C7Decrypt::Type7.decrypt_array(
68
69
  @known_values.map {|known_value| known_value[:ph]}
69
70
  )
70
71
  end
@@ -77,7 +78,7 @@ describe C7Decrypt do
77
78
 
78
79
  context "when decrypting Cisco Type-7 with a seed greater than 9" do
79
80
  before(:each) do
80
- @decrypt_hash = C7Decrypt.decrypt("15000E010723382727")
81
+ @decrypt_hash = C7Decrypt::Type7.decrypt("15000E010723382727")
81
82
  end
82
83
 
83
84
  subject{@decrypt_hash}
@@ -95,7 +96,7 @@ describe C7Decrypt do
95
96
  }
96
97
 
97
98
  @known_config_lines.keys.each do |k,v|
98
- @encrypted_hashes << C7Decrypt.type_7_matches(k)
99
+ @encrypted_hashes << C7Decrypt::Type7.type_7_matches(k)
99
100
  end
100
101
  @encrypted_hashes.flatten!
101
102
  end
@@ -109,7 +110,7 @@ describe C7Decrypt do
109
110
  context "when encrypting single Cisco Type-7 hash" do
110
111
  before(:each) do
111
112
  @plaintext_hash = "cisco"
112
- @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash)
113
+ @encrypted_hash = C7Decrypt::Type7.encrypt(@plaintext_hash)
113
114
  end
114
115
 
115
116
  subject{@encrypted_hash}
@@ -121,7 +122,7 @@ describe C7Decrypt do
121
122
  before(:each) do
122
123
  @plaintext_hash = "cisco"
123
124
  @seed = 3
124
- @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash, @seed)
125
+ @encrypted_hash = C7Decrypt::Type7.encrypt(@plaintext_hash, @seed)
125
126
  end
126
127
 
127
128
  subject{@encrypted_hash}
@@ -129,7 +130,7 @@ describe C7Decrypt do
129
130
  it {should == "030752180500"}
130
131
 
131
132
  it "should decrypt back to the original plaintext hash" do
132
- C7Decrypt.decrypt(@encrypted_hash).should == @plaintext_hash
133
+ C7Decrypt::Type7.decrypt(@encrypted_hash).should == @plaintext_hash
133
134
  end
134
135
  end
135
136
 
@@ -137,7 +138,7 @@ describe C7Decrypt do
137
138
  before(:each) do
138
139
  @plaintext_hash = "cisco"
139
140
  @seeds = 0..15
140
- @encrypted_hashes = @seeds.map {|seed| C7Decrypt.encrypt(@plaintext_hash, seed)}
141
+ @encrypted_hashes = @seeds.map {|seed| C7Decrypt::Type7.encrypt(@plaintext_hash, seed)}
141
142
  end
142
143
 
143
144
  subject{@encrypted_hashes}
@@ -145,7 +146,7 @@ describe C7Decrypt do
145
146
 
146
147
  it "should decrypt back to the original plaintext hashes" do
147
148
  @encrypted_hashes.each do |encrypted_hash|
148
- C7Decrypt.decrypt(encrypted_hash).should == @plaintext_hash
149
+ C7Decrypt::Type7.decrypt(encrypted_hash).should == @plaintext_hash
149
150
  end
150
151
  end
151
152
  end
@@ -154,7 +155,7 @@ describe C7Decrypt do
154
155
  before(:each) do
155
156
  @encrypted_hashes = []
156
157
  @known_values.each do |known_value|
157
- @encrypted_hashes << C7Decrypt.encrypt(known_value[:pt], known_value[:seed])
158
+ @encrypted_hashes << C7Decrypt::Type7.encrypt(known_value[:pt], known_value[:seed])
158
159
  end
159
160
  end
160
161
 
@@ -167,19 +168,19 @@ describe C7Decrypt do
167
168
  context "when encrypting known value matches individually as an array" do
168
169
  before(:each) do
169
170
  @plaintext_passwords = @known_values.map {|known_value| known_value[:pt]}.uniq
170
- @encrypted_passwords = C7Decrypt.encrypt_array(@plaintext_passwords)
171
+ @encrypted_passwords = C7Decrypt::Type7.encrypt_array(@plaintext_passwords)
171
172
  end
172
173
 
173
174
  subject{@encrypted_passwords}
174
175
  its(:class) {should == ::Array}
175
176
  its(:size) {should == @plaintext_passwords.size}
176
- it {should == @plaintext_passwords.map {|plaintext_password| C7Decrypt.encrypt(plaintext_password)}}
177
+ it {should == @plaintext_passwords.map {|plaintext_password| C7Decrypt::Type7.encrypt(plaintext_password)}}
177
178
  end
178
179
 
179
180
  context "when encrypting Cisco Type-7" do
180
181
  before(:each) do
181
182
  @plaintext_hash = "remcisco"
182
- @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash)
183
+ @encrypted_hash = C7Decrypt::Type7.encrypt(@plaintext_hash)
183
184
  end
184
185
 
185
186
  subject{@encrypted_hash}
@@ -191,7 +192,7 @@ describe C7Decrypt do
191
192
  before(:each) do
192
193
  @plaintext_hash = "remcisco"
193
194
  @seed = 15
194
- @encrypted_hash = C7Decrypt.encrypt(@plaintext_hash, @seed)
195
+ @encrypted_hash = C7Decrypt::Type7.encrypt(@plaintext_hash, @seed)
195
196
  end
196
197
 
197
198
  subject{@encrypted_hash}
@@ -201,31 +202,41 @@ describe C7Decrypt do
201
202
 
202
203
  context "when trying to decrypt a hash with an invalid first character" do
203
204
  it "should raise an InvalidFirstCharacter Exception" do
204
- expect { C7Decrypt.decrypt("AA000E010723382727") }.to raise_error(C7Decrypt::InvalidFirstCharacter)
205
+ expect {
206
+ C7Decrypt::Type7.decrypt("AA000E010723382727")
207
+ }.to raise_error(C7Decrypt::Type7::InvalidFirstCharacter)
205
208
  end
206
209
  end
207
210
 
208
211
  context "when trying to decrypt a hash with an invalid character" do
209
212
  it "should raise an InvalidFirstCharacter Exception" do
210
- expect { C7Decrypt.decrypt("06000**E010723382727") }.to raise_error(C7Decrypt::InvalidCharacter)
213
+ expect {
214
+ C7Decrypt::Type7.decrypt("06000**E010723382727")
215
+ }.to raise_error(C7Decrypt::Type7::InvalidCharacter)
211
216
  end
212
217
  end
213
218
 
214
219
  context "when trying to decrypt a hash with an odd number of characters" do
215
220
  it "should raise an InvalidFirstCharacter Exception" do
216
- expect { C7Decrypt.decrypt("06000E01723382727") }.to raise_error(C7Decrypt::OddNumberOfCharacters)
221
+ expect {
222
+ C7Decrypt::Type7.decrypt("06000E01723382727")
223
+ }.to raise_error(C7Decrypt::Type7::OddNumberOfCharacters)
217
224
  end
218
225
  end
219
226
 
220
227
  context "when trying to encrypt a hash with an invalid high encryption seed" do
221
228
  it "should raise an InvalidFirstCharacter Exception" do
222
- expect { C7Decrypt.encrypt("bananas", 16) }.to raise_error(C7Decrypt::InvalidEncryptionSeed)
229
+ expect {
230
+ C7Decrypt::Type7.encrypt("bananas", 16)
231
+ }.to raise_error(C7Decrypt::Type7::InvalidEncryptionSeed)
223
232
  end
224
233
  end
225
234
 
226
235
  context "when trying to encrypt a hash with an invalid low encryption seed" do
227
236
  it "should raise an InvalidFirstCharacter Exception" do
228
- expect { C7Decrypt.encrypt("bananas", -1) }.to raise_error(C7Decrypt::InvalidEncryptionSeed)
237
+ expect {
238
+ C7Decrypt::Type7.encrypt("bananas", -1)
239
+ }.to raise_error(C7Decrypt::Type7::InvalidEncryptionSeed)
229
240
  end
230
241
  end
231
242
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c7decrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Claudius
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-19 00:00:00.000000000 Z
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fuzzbert
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.14.1
33
+ version: 3.0.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.14.1
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,12 +84,12 @@ files:
70
84
  - bin/c7decrypt
71
85
  - c7decrypt.gemspec
72
86
  - lib/c7decrypt.rb
73
- - lib/c7decrypt/c7decrypt.rb
87
+ - lib/c7decrypt/type7.rb
74
88
  - lib/c7decrypt/version.rb
75
- - spec/c7decrypt_spec.rb
76
89
  - spec/example_configs/bad_canned_example.txt
77
90
  - spec/example_configs/empty_example.txt
78
91
  - spec/example_configs/simple_canned_example.txt
92
+ - spec/type7_spec.rb
79
93
  homepage: http://rubygems.org/gems/c7decrypt
80
94
  licenses: []
81
95
  metadata: {}
@@ -1,192 +0,0 @@
1
- module C7Decrypt
2
- module Constants
3
- # Vigenere translation table (these are our key values for decryption)
4
- VT_TABLE = [
5
- 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e,
6
- 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44,
7
- 0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39,
8
- 0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76, 0x39, 0x38, 0x37, 0x33,
9
- 0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37
10
- ]
11
-
12
- # Regexes for extracting hashes from configs
13
- TYPE_7_REGEXES = [
14
- /enable password 7 ([A-Z0-9]+)/,
15
- /username [A-Z0-9]+ password 7 ([A-Z0-9]+)/,
16
- /password 7 ([A-Z0-9]+)/
17
- ]
18
- end
19
-
20
- class InvalidFirstCharacter < StandardError
21
- end
22
-
23
- class InvalidCharacter < StandardError
24
- end
25
-
26
- class OddNumberOfCharacters < StandardError
27
- end
28
-
29
- class InvalidEncryptionSeed < StandardError
30
- end
31
-
32
- # The Decryption Method for Cisco Type-7 Encrypted Strings
33
- # @param [String] the Cisco Type-7 Encrypted String
34
- # @raise [InvalidFirstCharacter,
35
- # InvalidCharacter,
36
- # OddNumberOfCharacters]
37
- # @return [String] the Decrypted String
38
- def self.decrypt(e_text)
39
- check_type_7_errors(e_text)
40
-
41
- d_text = ""
42
- seed = nil
43
-
44
- e_text.scan(/../).each_with_index do |char,i|
45
- if i == 0
46
- seed = char.to_i - 1
47
- else
48
- d_text += decrypt_char(char, i, seed)
49
- end
50
- end
51
-
52
- return d_text
53
- end
54
-
55
- # The Encryption Method for Cisco Type-7 Encrypted Strings
56
- # @param [String] the plaintext password
57
- # @param [String] the seed for the encryption used
58
- # @raise [InvalidEncryptionSeed,
59
- # InvalidFirstCharacter,
60
- # InvalidCharacter,
61
- # OddNumberOfCharacters]
62
- # @return [String] the encrypted password
63
- def self.encrypt(d_text, seed = 2)
64
- check_seed(seed)
65
-
66
- e_text = sprintf("%02d", seed)
67
-
68
- d_text.each_char.each_with_index do |d_char,i|
69
- e_text += encrypt_char(d_char, i, seed)
70
- end
71
-
72
- check_type_7_errors(e_text)
73
-
74
- return e_text
75
- end
76
-
77
- # The method for encrypting a single character
78
- # @param [String] the plain text char
79
- # @param [FixNum] the index of the char in plaintext string
80
- # @param [FixNum] the seed used in the encryption process
81
- # @return [String] the string of the encrypted char
82
- def self.encrypt_char(char, i, seed)
83
- sprintf("%02X", char.unpack('C')[0] ^ Constants::VT_TABLE[(i + seed) % 53])
84
- end
85
-
86
- # The method for decrypting a single character
87
- # @param [String] the encrypted char
88
- # @param [Integer] the index of the char pair in encrypted string
89
- # @param [Integer] the seed used in the decryption process
90
- # @return [String] the string of the decrypted char
91
- def self.decrypt_char(char, i, seed)
92
- (char.hex^Constants::VT_TABLE[(i + seed) % 53]).chr
93
- end
94
-
95
- # A helper method to decrypt an arracy of Cisco Type-7 Encrypted Strings
96
- # @param [Array>String] an array of Cisco Type-7 Encrypted Strings
97
- # @raise [InvalidFirstCharacter,
98
- # InvalidCharacter,
99
- # OddNumberOfCharacters]
100
- # @return [Array>String] an array of Decrypted Strings
101
- def self.decrypt_array(pw_array)
102
- pw_array.collect {|pw| decrypt(pw)}
103
- end
104
-
105
- # A helper method to encrypt an arracy of passwords
106
- # @param [Array>String] an array of plain-text passwords
107
- # @raise [InvalidEncryptionSeed,
108
- # InvalidFirstCharacter,
109
- # InvalidCharacter,
110
- # OddNumberOfCharacters]
111
- # @return [Array>String] an array of encrypted passwords
112
- def self.encrypt_array(pt_array, seed = 2)
113
- pt_array.collect {|pw| encrypt(pw, seed)}
114
- end
115
-
116
- # This method scans a raw config file for type 7 passwords and
117
- # decrypts them
118
- # @param [String] a string of the config file path that contains
119
- # Cisco Type-7 Encrypted Strings
120
- # @raise [InvalidFirstCharacter,
121
- # InvalidCharacter,
122
- # OddNumberOfCharacters]
123
- # @return [Array>String] an array of Decrypted Strings
124
- def self.decrypt_config(file)
125
- f = File.open(file, 'r').to_a
126
- decrypt_array(f.collect {|line| type_7_matches(line)}.flatten)
127
- end
128
-
129
- # This method scans a config line for encrypted type-7 passwords and
130
- # returns an array of results
131
- # @param [String] a line with potential encrypted type-7 passwords
132
- # @return [Array>String] an array of Cisco type-7 encrypted Strings
133
- def self.type_7_matches(string)
134
- Constants::TYPE_7_REGEXES.collect {|regex| string.scan(regex)}.flatten.uniq
135
- end
136
-
137
- # This method determines if an encrypted hash is corrupted/invalid
138
- # and throw a specific exeception
139
- # @param [String] the Cisco Type-7 Encrypted String
140
- # @raise [InvalidFirstCharacter, InvalidCharacter, OddNumberOfCharacters]
141
- # @return [Nil]
142
- def self.check_type_7_errors(e_text)
143
-
144
- valid_first_chars = (0..15).to_a.collect {|c| sprintf("%02d", c)}
145
- first_char = e_text[0,2]
146
-
147
- # Check for an invalid first character in the has
148
- unless valid_first_chars.include? first_char
149
- raise InvalidFirstCharacter,
150
- "'#{e_text}' hash contains an invalid first chracter (only '00' - '15' allowed)"
151
- end
152
-
153
- # Check for an invalid character in the hash
154
- unless e_text.match(/^[A-Z0-9]+$/)
155
- raise InvalidCharacter,
156
- "'#{e_text}' hash contains an invalid character (only upper-alpha numeric allowed)"
157
- end
158
-
159
- # Check for an odd number of characters in the hash
160
- unless e_text.size % 2 == 0
161
- raise OddNumberOfCharacters,
162
- "'#{e_text}' hash contains odd length of chars (only even number of chars allowed)"
163
- end
164
-
165
- return nil
166
-
167
- end
168
-
169
- # This method determines if an encryption seed is valid or not
170
- # and throw a specific exeception
171
- # @param [FixNum] the seed used in the encryption process
172
- # @raise [InvalidEncryptionSeed]
173
- # @return [Nil]
174
- def self.check_seed(seed)
175
- if seed < 0 ||
176
- seed > 15
177
-
178
- raise InvalidEncryptionSeed,
179
- "'#{seed.to_s}' seed is not a valid seed (only 0 - 15 allowed)"
180
- end
181
-
182
- return nil
183
- end
184
-
185
- #Definition of short-hand methods for the lazy
186
- #alias :d :decrypt
187
- #alias :e :encrypt
188
- #alias :d_a :decrypt_array
189
- #alias :e_a :encrypt_array
190
- #alias :d_c :decrypt_config
191
-
192
- end