Module: C7Decrypt::Type5

Defined in:
lib/c7decrypt/type5/type5.rb,
lib/c7decrypt/type5/constants.rb

Defined Under Namespace

Modules: Constants

Class Method Summary collapse

Class Method Details

.bit_specified_base64encode(input) ⇒ String

A helper method for bit specified base64 output (the format Type-5 hashes are in)

Parameters:

  • input (String)

Returns:

  • (String)

    encoded_input



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/c7decrypt/type5/type5.rb', line 55

def self.bit_specified_base64encode(input)
  b64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  input = input.bytes.to_a
  output = ""
  Constants::BYTE_INDEXES.each do |i3, i2, i1|
    b1, b2, b3 = i1 && input[i1] || 0, i2 && input[i2] || 0, i3 && input[i3] || 0
    output <<
      b64[  b1 & 0b00111111]         <<
      b64[((b1 & 0b11000000) >> 6) |
          ((b2 & 0b00001111) << 2)]  <<
      b64[((b2 & 0b11110000) >> 4) |
          ((b3 & 0b00000011) << 4)]  <<
      b64[ (b3 & 0b11111100) >> 2]
  end

  remainder = 3 - (16 % 3)
  remainder = 0 if remainder == 3

  return output[0..-1-remainder]
end

.cisco_md5_format(salt, hash) ⇒ Object

A helper method for formating Cisco Type-5 hashes



48
49
50
# File 'lib/c7decrypt/type5/type5.rb', line 48

def self.cisco_md5_format(salt, hash)
  return "$1$" + salt + "$" + hash
end

.encrypt(password, salt = generate_salt) ⇒ String

The Encryption Method for Cisco Type-5 Encrypted Strings

Parameters:

  • password (String)
  • salt (String) (defaults to: generate_salt)

Returns:

  • (String)

    formatted Type-5 hash



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/c7decrypt/type5/type5.rb', line 21

def self.encrypt(password, salt = generate_salt)
  password = password.encode("UTF-8")
  password.force_encoding("ASCII-8BIT")

  b = Digest::MD5.digest("#{password}#{salt}#{password}")
  a_string = "#{password}$1$#{salt}#{b * (password.length/16)}#{b[0...password.length % 16]}"

  password_length = password.length
  while password_length > 0
    a_string += (password_length & 1 != 0) ? "\x0" : password[0].chr
    password_length >>= 1
  end

  input = Digest::MD5.digest(a_string)

  1000.times do |index|
    c_string = ((index & 1 != 0) ? password : input)
    c_string += salt unless index % 3 == 0
    c_string += password unless index % 7 == 0
    c_string += ((index & 1 != 0) ? input : password)
    input = Digest::MD5.digest(c_string)
  end

  return cisco_md5_format(salt, bit_specified_base64encode(input))
end

.generate_salt(size = 4) ⇒ String

Generates a random salt using the same character set as the base64 encoding used by the hash encoder.

Returns:

  • (String)

    salt



79
80
81
# File 'lib/c7decrypt/type5/type5.rb', line 79

def self.generate_salt(size = 4)
  SecureRandom.base64((size * 6 / 8.0).ceil).tr("+", ".")[0...size]
end