class AdyenCse::Encrypter

Constants

PREFIX
VERSION

Attributes

cvc[RW]
expiry_month[RW]
expiry_year[RW]
generation_time[RW]
holder_name[RW]
number[RW]
public_key[R]

Public Class Methods

new(public_key) { |self rescue nil| ... } click to toggle source
# File lib/adyen_cse/encrypter.rb, line 14
def initialize(public_key)
  @public_key = public_key
  yield self rescue nil
  self.generation_time ||= Time.now
end
parse_public_key(public_key) click to toggle source
# File lib/adyen_cse/encrypter.rb, line 50
def self.parse_public_key(public_key)
  exponent, modulus = public_key.split("|").map { |n| n.to_i(16) }

  rsa = OpenSSL::PKey::RSA.new
  rsa.set_key(OpenSSL::BN.new(modulus), OpenSSL::BN.new(exponent), nil)
end

Public Instance Methods

card_data() click to toggle source
# File lib/adyen_cse/encrypter.rb, line 38
def card_data
  # keys sorted alphabetically
  {
    "cvc" => cvc,
    "expiryMonth" => expiry_month,
    "expiryYear" => expiry_year,
    "generationtime" => generation_time.utc.strftime("%FT%T.%LZ"),
    "holderName" => holder_name,
    "number" => number,
  }
end
encrypt!() click to toggle source
# File lib/adyen_cse/encrypter.rb, line 20
def encrypt!
  validate!

  key   = SecureRandom.random_bytes(32)
  nonce = SecureRandom.random_bytes(12)
  data  = card_data.to_json

  ccm = OpenSSL::CCM.new("AES", key, 8)
  encrypted_card = ccm.encrypt(data, nonce)

  rsa = self.class.parse_public_key(public_key)
  encrypted_aes_key = rsa.public_encrypt(key)

  encrypted_card_component = nonce + encrypted_card

  [PREFIX, VERSION, "$", Base64.strict_encode64(encrypted_aes_key), "$", Base64.strict_encode64(encrypted_card_component)].join
end

Private Instance Methods

validate!() click to toggle source
# File lib/adyen_cse/encrypter.rb, line 59
def validate!
  %w(holder_name number expiry_month expiry_year cvc generation_time).each do |param|
    raise ArgumentError, "param `#{param}' is required" if instance_variable_get("@#{param}").nil?
  end
end