Class: Mac

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

Overview

Provides methods to sign and verify timestamped messages with HMAC SHA256.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message:, secret:, timed: true) ⇒ Mac

Sets up a message to be signed/verified with a secret.



4
5
6
7
8
# File 'lib/mac.rb', line 4

def initialize(message:, secret:, timed: true)
  @message = message
  @secret = secret
  @timed = timed
end

Instance Attribute Details

#signatureObject (readonly)

Returns the value of attribute signature.



17
18
19
# File 'lib/mac.rb', line 17

def signature
  @signature
end

#timestampObject (readonly)

Returns the value of attribute timestamp.



17
18
19
# File 'lib/mac.rb', line 17

def timestamp
  @timestamp
end

Class Method Details

.sign(message:, secret:, timed: true, hexdigest: true) ⇒ Object

Sets up a message and calculates its current signature.



11
12
13
14
15
# File 'lib/mac.rb', line 11

def self.sign(message:, secret:, timed: true, hexdigest: true)
  new(message: message, secret: secret).tap do |mac|
    mac.sign timestamp: (Time.now if timed), hexdigest: hexdigest
  end
end

Instance Method Details

#sign(timestamp: nil, hexdigest: true) ⇒ Object

Calculates the signature of the message.



26
27
28
29
30
31
32
33
34
# File 'lib/mac.rb', line 26

def sign(timestamp: nil, hexdigest: true)
  @timestamp = timestamp.to_i.to_s if timestamp
  payload = [@timestamp, @message].compact.join '.'
  @signature = if hexdigest
    OpenSSL::HMAC.hexdigest 'SHA256', @secret, payload
  else
    Base64.strict_encode64(OpenSSL::HMAC.digest 'SHA256', @secret, payload)
  end
end

#signed?(signature:, timestamp: nil, hexdigest: true) ⇒ Boolean

Returns whether the provided signature and timestamp match the signature of the message.

Returns:

  • (Boolean)


20
21
22
23
# File 'lib/mac.rb', line 20

def signed?(signature:, timestamp: nil, hexdigest: true)
  sign hexdigest: hexdigest, timestamp: timestamp
  Rack::Utils.secure_compare @signature, signature
end