Class: Multipassify

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(secret) ⇒ Multipassify

Returns a new instance of Multipassify.



9
10
11
12
13
14
15
16
17
# File 'lib/multipassify.rb', line 9

def initialize(secret)
  block_size = 16

  # Use the Multipass secret to derive two cryptographic keys,
  # one for encryption, one for signing
  hash = OpenSSL::Digest.new("sha256").digest(secret)
  self.encryptionKey = hash[0,block_size]
  self.signingKey = hash[block_size, 32]
end

Instance Attribute Details

#encryptionKeyObject

Returns the value of attribute encryptionKey.



7
8
9
# File 'lib/multipassify.rb', line 7

def encryptionKey
  @encryptionKey
end

#signingKeyObject

Returns the value of attribute signingKey.



7
8
9
# File 'lib/multipassify.rb', line 7

def signingKey
  @signingKey
end

Instance Method Details

#encode(obj) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/multipassify.rb', line 19

def encode(obj)
  return if !obj

  # Store the current time in ISO8601 format.
  # The token will only be valid for a small timeframe around this timestamp.
  obj["created_at"] = Time.now.iso8601

  # Serialize the customer data to JSON and encrypt it
  cipherText = self.encrypt(obj.to_json)

  # Create a signature (message authentication code) of the ciphertext
  # and encode everything using URL-safe Base64 (RFC 4648)
  Base64.urlsafe_encode64(cipherText + self.sign(cipherText))
end

#encrypt(plaintext) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/multipassify.rb', line 34

def encrypt(plaintext)
  cipher = OpenSSL::Cipher.new("aes-128-cbc")
  cipher.encrypt
  cipher.key = self.encryptionKey

  ### Use a random IV
  cipher.iv = iv = cipher.random_iv

  # Use IV as first block of ciphertext
  iv + cipher.update(plaintext) + cipher.final
end

#generate_url(obj, domain) ⇒ Object



46
47
48
49
# File 'lib/multipassify.rb', line 46

def generate_url(obj, domain)
  return if !domain
  return "https://" + domain + "/account/login/multipass/" + self.encode(obj)
end

#sign(data) ⇒ Object



51
52
53
# File 'lib/multipassify.rb', line 51

def sign(data)
  OpenSSL::HMAC.digest("sha256", self.signingKey, data)
end