Class: PBKDF2

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

Constant Summary collapse

VERSION =
"0.0.1"

Class Method Summary collapse

Class Method Details

.calculate!(options) ⇒ Object

the bit that actually does the calculating



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/pbkdf2.rb', line 75

def self.calculate!(options)
  # how many blocks we'll need to calculate (the last may be truncated)
  blocks_needed = (options[:key_length].to_f / options[:hash_function].size).ceil
  # reset
  value = ""
  # main block-calculating loop:
  1.upto(blocks_needed) do |block_num|
   value << calculate_block(options,block_num)
  end
  # truncate to desired length:
  value = value.slice(0,options[:key_length]).unpack("H*").first
  value
end

.calculate_block(options, block_num) ⇒ Object

this is a translation of the helper function “F” defined in the spec



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/pbkdf2.rb', line 60

def self.calculate_block(options, block_num)
  # u_1:
  u = prf(options, options[:salt]+[block_num].pack("N"))
  ret = u
  # u_2 through u_c:
  2.upto(options[:iterations]) do
    # calculate u_n
    u = prf(options, u)
    # xor it with the previous results
    ret = ret^u
  end
  ret
end

.hex_string(options = {}) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:

  • _self (PBKDF2)

    the object that the method was called on

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/pbkdf2.rb', line 31

def self.hex_string(options = {})

  yield self if block_given?

  # Raise errors for unset options, all are mandatory
  raise ArgumentError, ":password is not set" if options[:password].nil?
  raise ArgumentError, ":salt is not set" if options[:salt].nil?
  raise ArgumentError, ":iterations is not set" if options[:iterations].nil?
  raise ArgumentError, ":key_length is not set" if options[:key_length].nil?
  raise ArgumentError, ":hash_function is not set" if options[:hash_function].nil?

  options[:hash_function] = options[:hash_function].new
  validate(options)
  options[:key_length] = options[:key_length]/8

  calculate!(options)
end

.prf(options, data) ⇒ Object



55
56
57
# File 'lib/pbkdf2.rb', line 55

def self.prf(options, data)
  OpenSSL::HMAC.digest(options[:hash_function], options[:password], data)
end

.validate(options) ⇒ Object

Raises:

  • (ArgumentError)


49
50
51
52
53
# File 'lib/pbkdf2.rb', line 49

def self.validate(options)
  raise ArgumentError, "Key is too short (< 1)" if options[:key_length] < 1
  raise ArgumentError, "key is too long for hash function" if options[:key_length]/8 > ((2**32 - 1) * options[:hash_function].size)
  raise ArgumentError, "iterations can't be less than 1" if options[:iterations] < 1
end