Class: UnixCrypt::SHABase

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

Direct Known Subclasses

SHA256, SHA512

Class Method Summary collapse

Methods inherited from Base

bit_specified_base64encode, build, construct_password, generate_salt, hash, prepare_password

Class Method Details

.apply_rounds_bounds(rounds) ⇒ Object



41
42
43
44
45
# File 'lib/unix_crypt/sha.rb', line 41

def self.apply_rounds_bounds(rounds)
  rounds = 1000        if rounds < 1000
  rounds = 999_999_999 if rounds > 999_999_999
  rounds
end

.default_rounds ⇒ Object



6
# File 'lib/unix_crypt/sha.rb', line 6

def self.default_rounds; 5000; end

.default_salt_length ⇒ Object



4
# File 'lib/unix_crypt/sha.rb', line 4

def self.default_salt_length; 16; end

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



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/unix_crypt/sha.rb', line 8

def self.internal_hash(password, salt, rounds = nil)
  rounds = apply_rounds_bounds(rounds || default_rounds)
  salt = salt[0..15]

  b = digest.digest("#{password}#{salt}#{password}")

  a_string = password + salt + b * (password.length/length) + b[0...password.length % length]

  password_length = password.length
  while password_length > 0
    a_string += (password_length & 1 != 0) ? b : password
    password_length >>= 1
  end

  input = digest.digest(a_string)

  dp = digest.digest(password * password.length)
  p = dp * (password.length/length) + dp[0...password.length % length]

  ds = digest.digest(salt * (16 + input.bytes.first))
  s = ds * (salt.length/length) + ds[0...salt.length % length]

  rounds.times do |index|
    c_string = ((index & 1 != 0) ? p : input)
    c_string += s unless index % 3 == 0
    c_string += p unless index % 7 == 0
    c_string += ((index & 1 != 0) ? input : p)
    input = digest.digest(c_string)
  end

  input
end

.max_salt_length ⇒ Object



5
# File 'lib/unix_crypt/sha.rb', line 5

def self.max_salt_length; 16; end

.rounds_marker(rounds) ⇒ Object



47
48
49
50
51
# File 'lib/unix_crypt/sha.rb', line 47

def self.rounds_marker(rounds)
  if rounds && rounds != default_rounds
    "rounds=#{apply_rounds_bounds(rounds)}$"
  end
end