Skip to content

Instantly share code, notes, and snippets.

@bsodmike
Last active February 4, 2018 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsodmike/4d25c4dc4407644127aea02aa558a2e1 to your computer and use it in GitHub Desktop.
Save bsodmike/4d25c4dc4407644127aea02aa558a2e1 to your computer and use it in GitHub Desktop.
POC Encryption in Ruby for Discussion at Level1 Techs
# Copyright (c) 2018 Michael de Silva, CTO Secure Cloud Solutions (siliconcloud.tech) & Inertialbox (inertialbox.com)
# Blog: mwdesilva.com // Expertise: desilva.io // Twitter: @bsodmike
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
require 'psych'
require 'openssl'
class BrowserSimulator
def initialize(api)
@api = api
end
end
class SandboxApi
def initialize(encrypted_card)
@encrypted_card = encrypted_card
end
def decrypt_card(encryptor, iv, salt, password)
encryptor.decrypt(iv, salt, password, @encrypted_card)
end
end
class Encryptor
def initialize
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
@cipher.encrypt
@iv = @cipher.random_iv
end
def encrypt(payload, password)
salt = OpenSSL::Random.random_bytes 16
iter = 20000
key_len = @cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, key_len, digest)
@cipher.key = key
encrypted = @cipher.update payload
encrypted << @cipher.final
{
iv: @iv,
salt: salt,
encrypted: encrypted
}
end
def decrypt(iv, salt, password, encrypted)
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
cipher.iv = iv # the one generated with #random_iv
salt = salt
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iter, key_len, digest)
cipher.key = key
decrypted = cipher.update encrypted
decrypted << cipher.final
end
end
card = {
merchant: 'AMEX',
card_number: '1234123412341234',
name: 'Mr. Krzanich Meltdown'
}
puts "Card object (Hash), to be encrypted\n"
puts card
serialised_card = Psych.dump(card)
encryptor = Encryptor.new
password = 'e6279ea77e8aa17bd530d047d4a555e6c9708fffe90c248d9f818429e3e16b13'
puts "\n\nPassword used to encrypt card details: #{password}"
# Serialise card object to YAML first.
encrypted_hsh = encryptor.encrypt(serialised_card, password)
# This is only exposed here for POC's sake to be quick.
encryption_iv = encrypted_hsh[:iv]
encryption_salt = encrypted_hsh[:salt]
api = SandboxApi.new(encrypted_hsh[:encrypted])
puts "\n**** Transmit Encrypted card payload to backend\n #{encrypted_hsh[:encrypted]}\n****\n\n"
decrypted = api.decrypt_card(encryptor, encryption_iv, encryption_salt, password)
card = Psych.load decrypted
puts "Decrypting card payload\n"
puts card
-> % ruby secure_forms.rb
Card object (Hash), to be encrypted
{:merchant=>"AMEX", :card_number=>"1234123412341234", :name=>"Mr. Krzanich Meltdown"}
Password used to encrypt card details: e6279ea77e8aa17bd530d047d4a555e6c9708fffe90c248d9f818429e3e16b13
**** Transmit Encrypted card payload to backend
�~x�x !:<�Қ'XM;����%�3h����k���|�<��U���0��v��}�xeBКI���E�0T����}|�TH�P��-��*
****
Decrypting card payload
{:merchant=>"AMEX", :card_number=>"1234123412341234", :name=>"Mr. Krzanich Meltdown"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment