Module: R2D2::Util

Included in:
AndroidPayToken, GooglePayToken
Defined in:
lib/r2d2/util.rb

Instance Method Summary collapse

Instance Method Details

#decrypt_message(encrypted_data, symmetric_key) ⇒ Object



47
48
49
50
51
52
# File 'lib/r2d2/util.rb', line 47

def decrypt_message(encrypted_data, symmetric_key)
  decipher = OpenSSL::Cipher::AES128.new(:CTR)
  decipher.decrypt
  decipher.key = symmetric_key
  decipher.update(Base64.decode64(encrypted_data)) + decipher.final
end

#derive_hkdf_keys(ephemeral_public_key, shared_secret, info) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/r2d2/util.rb', line 32

def derive_hkdf_keys(ephemeral_public_key, shared_secret, info)
  key_material = Base64.decode64(ephemeral_public_key) + shared_secret
  hkdf_bytes = hkdf(key_material, info)
  {
    symmetric_encryption_key: hkdf_bytes[0..15],
    mac_key: hkdf_bytes[16..32]
  }
end

#generate_shared_secret(private_key, ephemeral_public_key) ⇒ Object



25
26
27
28
29
30
# File 'lib/r2d2/util.rb', line 25

def generate_shared_secret(private_key, ephemeral_public_key)
  ec = OpenSSL::PKey::EC.new('prime256v1')
  bn = OpenSSL::BN.new(Base64.decode64(ephemeral_public_key), 2)
  point = OpenSSL::PKey::EC::Point.new(ec.group, bn)
  private_key.dh_compute_key(point)
end

#to_length_value(*chunks) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/r2d2/util.rb', line 54

def to_length_value(*chunks)
  value = ''
  chunks.each do |chunk|
    chunk_size = 4.times.map do |index|
      (chunk.bytesize >> (8 * index)) & 0xFF
    end
    value << chunk_size.pack('C*')
    value << chunk
  end
  value
end

#verify_mac(mac_key, encrypted_message, tag) ⇒ Object



41
42
43
44
45
# File 'lib/r2d2/util.rb', line 41

def verify_mac(mac_key, encrypted_message, tag)
  digest = OpenSSL::Digest.new('sha256')
  mac = OpenSSL::HMAC.digest(digest, mac_key, Base64.decode64(encrypted_message))
  raise TagVerificationError unless secure_compare(mac, Base64.decode64(tag))
end