Class: Linzer::HMAC::Key

Inherits:
Key
  • Object
show all
Defined in:
lib/linzer/hmac.rb

Overview

HMAC signing key implementation.

HMAC-SHA256 is the primary supported algorithm, using the hmac-sha256 algorithm identifier.

Examples:

Generating a new key

key = Linzer.generate_hmac_sha256_key("shared-key")

Using existing secret material

secret = Base64.decode64(ENV["SIGNING_SECRET"])
key = Linzer.new_hmac_sha256_key(secret, "api-key")

See Also:

Instance Attribute Summary

Attributes inherited from Key

#material

Instance Method Summary collapse

Methods inherited from Key

#initialize, #key_id

Constructor Details

This class inherits a constructor from Linzer::Key

Instance Method Details

#inspectString

Returns a safe string representation that doesn’t leak the secret.

The key material is intentionally excluded from the output to prevent accidental exposure in logs or error messages.

Returns:

  • (String)

    A string representation without the secret key



75
76
77
78
79
80
81
82
83
84
# File 'lib/linzer/hmac.rb', line 75

def inspect
  vars =
    instance_variables
      .reject { |v| v == :@material } # don't leak secret unneccesarily
      .map do |n|
        "#{n}=#{instance_variable_get(n).inspect}"
      end
  oid = Digest::SHA2.hexdigest(object_id.to_s)[48..63]
  "#<%s:0x%s %s>" % [self.class, oid, vars.join(", ")]
end

#private?Boolean

HMAC keys can always sign (they contain the secret).

Returns:

  • (Boolean)

    true if key material is present



59
60
61
# File 'lib/linzer/hmac.rb', line 59

def private?
  !material.nil?
end

#public?Boolean

HMAC keys are symmetric, not public/private.

Returns:

  • (Boolean)

    always false for HMAC keys



65
66
67
# File 'lib/linzer/hmac.rb', line 65

def public?
  false
end

#sign(data) ⇒ String

Signs data using HMAC.

Parameters:

  • data (String)

    The data to sign

Returns:

  • (String)

    The HMAC digest (32 bytes for SHA-256)



41
42
43
# File 'lib/linzer/hmac.rb', line 41

def sign(data)
  OpenSSL::HMAC.digest(@params[:digest], material, data)
end

#validateObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



32
33
34
35
# File 'lib/linzer/hmac.rb', line 32

def validate
  super
  validate_digest
end

#verify(signature, data) ⇒ Boolean

Verifies an HMAC signature using constant-time comparison.

Uses OpenSSL.secure_compare to prevent timing attacks where an attacker could measure response times to guess valid signatures.

Parameters:

  • signature (String)

    The signature bytes to verify

  • data (String)

    The data that was signed

Returns:

  • (Boolean)

    true if the signature is valid, false otherwise



53
54
55
# File 'lib/linzer/hmac.rb', line 53

def verify(signature, data)
  OpenSSL.secure_compare(signature, sign(data))
end