Class: HKDF
- Inherits:
-
Object
- Object
- HKDF
- Defined in:
- lib/hkdf.rb,
lib/hkdf/version.rb
Overview
Provide HMAC-based Extract-and-Expand Key Derivation Function (HKDF) for Ruby.
Constant Summary collapse
- DEFAULT_ALGOTIHM =
Default hash algorithm to use for HMAC.
"SHA256"
- DEFAULT_READ_SIZE =
Default buffer size for reading source IO.
512 * 1024
- VERSION =
:nodoc:
"1.0.0"
Instance Method Summary collapse
-
#algorithm ⇒ Object
Returns the hash algorithm this instance was configured with.
-
#initialize(source, options = {}) ⇒ HKDF
constructor
Create a new HKDF instance with then provided
source
key material. -
#inspect ⇒ Object
:nodoc:.
-
#max_length ⇒ Object
Maximum length that can be derived per the RFC.
-
#read(length) ⇒ Object
Read the next
length
bytes from the stream. -
#read_hex(length) ⇒ Object
Read the next
length
bytes from the stream and return them hex encoded. -
#rewind ⇒ Object
Adjust reading position back to the beginning.
-
#seek(position) ⇒ Object
Adjust the reading position to an arbitrary offset.
Constructor Details
#initialize(source, options = {}) ⇒ HKDF
Create a new HKDF instance with then provided source
key material.
Options:
-
algorithm:
hash function to use (defaults to SHA-256) -
info:
optional context and application specific information -
salt:
optional salt value (a non-secret random value) -
read_size:
buffer size when reading from a source IO
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/hkdf.rb', line 20 def initialize(source, = {}) source = StringIO.new(source) if source.is_a?(String) algorithm = .fetch(:algorithm, DEFAULT_ALGOTIHM) @digest = OpenSSL::Digest.new(algorithm) @info = .fetch(:info, "") salt = [:salt] salt = 0.chr * @digest.digest_length if salt.nil? || salt.empty? read_size = .fetch(:read_size, DEFAULT_READ_SIZE) @prk = generate_prk(salt, source, read_size) @position = 0 @blocks = [""] end |
Instance Method Details
#algorithm ⇒ Object
Returns the hash algorithm this instance was configured with.
37 38 39 |
# File 'lib/hkdf.rb', line 37 def algorithm @digest.name end |
#inspect ⇒ Object
:nodoc:
79 80 81 |
# File 'lib/hkdf.rb', line 79 def inspect "#{to_s[0..-2]} algorithm=#{@digest.name.inspect} info=#{@info.inspect}>" end |
#max_length ⇒ Object
Maximum length that can be derived per the RFC.
42 43 44 |
# File 'lib/hkdf.rb', line 42 def max_length @max_length ||= @digest.digest_length * 255 end |
#read(length) ⇒ Object
Read the next length
bytes from the stream. Will raise RangeError
if you attempt to read beyond #max_length
.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/hkdf.rb', line 60 def read(length) new_position = length + @position raise RangeError, "requested #{length} bytes, only #{max_length} available" if new_position > max_length generate_blocks(new_position) start = @position @position = new_position @blocks.join.slice(start, length) end |
#read_hex(length) ⇒ Object
Read the next length
bytes from the stream and return them hex encoded. Will raise RangeError
if you attempt to read beyond #max_length
.
74 75 76 |
# File 'lib/hkdf.rb', line 74 def read_hex(length) read(length).unpack1("H*") end |
#rewind ⇒ Object
Adjust reading position back to the beginning.
55 56 57 |
# File 'lib/hkdf.rb', line 55 def rewind seek(0) end |
#seek(position) ⇒ Object
Adjust the reading position to an arbitrary offset. Will raise RangeError
if you attempt to seek longer than #max_length
.
48 49 50 51 52 |
# File 'lib/hkdf.rb', line 48 def seek(position) raise RangeError, "cannot seek past #{max_length}" if position > max_length @position = position end |