Skip to content

Instantly share code, notes, and snippets.

@ivanvc
Created September 9, 2009 17:41
Show Gist options
  • Save ivanvc/183918 to your computer and use it in GitHub Desktop.
Save ivanvc/183918 to your computer and use it in GitHub Desktop.
class CryptoTest
attr_reader :key, :iv
# Initiliaze it with a hash
# Possible options: key, and initialization vector
# examples
# CryptoTest.new #=> Will generate random iv and key
# CryptoTest.new(:key => "hexadecimal string") #=> Will generate random initialization vector
# CryptoTest.new(:iv => "hexadecimal string") #=> Will generate random key
# CryptoTest.new(:iv => "hexadecimal string", :key => "hexadecimal string") #=> Won't generate anything
def initialize(*args)
options = args.pop || {}
options = {} unless options.is_a?(Hash)
@provider = begin
OpenSSL::Cipher::Cipher.new(options[:crypto_provider] || "aes-128-cbc")
rescue
OpenSSL::Cipher::Cipher.new("aes-128-cbc")
end
set_key_and_iv(options)
end
# Encrypt a text
# Call it with a plain string, can flush the key and iv. Will return a hash with the key, iv and the crypted text
# examples
# crypto_test.encrypt("blah") #=> Will keep iv and key
# crypto_test.encrypt("blah", false) #=> Will keep iv and key
# crypto_test.encrypt("blah", true) #=> Will regenerate key and iv
def encrypt(text, flush = false)
set_key_and_iv(flush)
@provider.encrypt
@provider.key = @key
@provider.iv = @iv
encrypted = @provider.update(text)
encrypted << @provider.final
{ :key => key,
:iv => iv,
:cipher_text => self.class.binary_to_hex(encrypted).to_s }
end
# Decrypt a text
# Call it with a hexadecimal string, can change the value of iv and key too.
# examples
# crypto_test.decrypt("2b3acc12") #=> Will keep iv and key
# crypto_test.decrypt("2b3acc12", {}) #=> Will keep iv and key
# crypto_test.decrypt("2b3acc12", {:key => "12ff34"}) #=> Will keep iv and key will be replaced
# crypto_test.decrypt("2b3acc12", {:iv => "12ff34"}) #=> Will keep key and iv will be replaced
# crypto_test.decrypt("2b3acc12", {:key => "12ff34", :iv => "12ff34"}) #=> Will replace key and iv
def decrypt(cipher_text, options = {})
set_key_and_iv(options)
@provider.decrypt
@provider.key = @key
@provider.iv = @iv
decrypted = @provider.update(self.class.hex_to_binary(cipher_text))
decrypted << @provider.final
{ :key => key,
:iv => iv,
:plain_text => decrypted }
end
# Returns current iv value in hexadecimal
def iv
self.class.binary_to_hex(@iv).to_s
end
# Returns current key value in hexadecimal
def key
self.class.binary_to_hex(@key).to_s
end
def self.binary_to_hex(bin) #:nodoc:
bin.unpack("H*") rescue nil
end
def self.hex_to_binary(hex) #:nodoc:
[hex.gsub(/[^0-9a-f]/i, '')].pack("H*") rescue nil
end
private
def set_key_and_iv(*args) #:nodoc:
flush, values = false, {}
args.flatten.each do |arg|
case arg
when TrueClass, FalseClass
flush = arg
when Hash
values = arg
end
end
%w{key iv}.each do |value|
if flush || values[value.to_sym] || !send(value) || send(value).size == 0
send "#{value}=", self.class.hex_to_binary(values[value.to_sym]) || @provider.send("random_#{value}")
end
end
end
def key=(new_key) #:nodoc:
@key = new_key
end
def iv=(new_iv) #:nodoc:
@iv = new_iv
end
end
require 'rubygems'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment