Class: UnixCrypt::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/unix_crypt/base.rb

Direct Known Subclasses

DES, MD5, SHABase

Class Method Summary collapse

Class Method Details

.bit_specified_base64encode(input) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/unix_crypt/base.rb', line 26

def self.bit_specified_base64encode(input)
  b64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  input = input.bytes.to_a
  output = +""
  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 - (length % 3)
  remainder = 0 if remainder == 3
  output[0..-1-remainder]
end

.build(password, salt = nil, rounds = nil) ⇒ Object



2
3
4
5
6
7
8
9
# File 'lib/unix_crypt/base.rb', line 2

def self.build(password, salt = nil, rounds = nil)
  salt ||= generate_salt
  if salt.length > max_salt_length
    raise UnixCrypt::SaltTooLongError, "Salts longer than #{max_salt_length} characters are not permitted"
  end

  construct_password(password, salt, rounds)
end

.construct_password(password, salt, rounds) ⇒ Object



22
23
24
# File 'lib/unix_crypt/base.rb', line 22

def self.construct_password(password, salt, rounds)
  "$#{identifier}$#{rounds_marker rounds}#{salt}$#{hash(password, salt, rounds)}"
end

.generate_salt ⇒ Object



15
16
17
18
19
# File 'lib/unix_crypt/base.rb', line 15

def self.generate_salt
  # Generates a random salt using the same character set as the base64 encoding
  # used by the hash encoder.
  SecureRandom.base64((default_salt_length * 6 / 8.0).ceil).tr("+", ".")[0...default_salt_length]
end

.hash(password, salt, rounds = nil) ⇒ Object



11
12
13
# File 'lib/unix_crypt/base.rb', line 11

def self.hash(password, salt, rounds = nil)
  bit_specified_base64encode internal_hash(prepare_password(password), salt, rounds)
end

.prepare_password(password) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/unix_crypt/base.rb', line 46

def self.prepare_password(password)
  # For Ruby 1.9+, convert the password to UTF-8, then treat that new string
  # as binary for the digest methods.
  if password.respond_to?(:encode)
    password = password.encode("UTF-8")
    password.force_encoding("ASCII-8BIT")
  end

  password
end

.rounds_marker(rounds) ⇒ Object



57
58
59
# File 'lib/unix_crypt/base.rb', line 57

def self.rounds_marker(rounds)
  nil
end