c7decrypt 0.2.6 → 0.3.0

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: 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