Skip to content

Instantly share code, notes, and snippets.

@sbfaulkner
Created July 7, 2015 13:29
Show Gist options
  • Save sbfaulkner/2433e27dc595d3e0db98 to your computer and use it in GitHub Desktop.
Save sbfaulkner/2433e27dc595d3e0db98 to your computer and use it in GitHub Desktop.
cryptography tests
#!/usr/bin/env ruby
require 'openssl'
require 'base64'
require 'builder'
require 'securerandom'
require 'faker'
tests = %i(rsa)
I18n.enforce_available_locales = true
secret = "password4testing!"
data = Faker::Lorem.paragraph(2, true, 3)
puts "\nRandom text…"
puts data
if tests.include? :mac
digest = OpenSSL::Digest::SHA256.new
hmac = OpenSSL::HMAC.hexdigest(digest, secret, data)
puts "\nHMAC…"
puts hmac
end
if tests.include? :symmetric
######################################################################
#
# SYMMETRIC ENCRYPTION
#
# STEP 1... construct cipher
cipher = OpenSSL::Cipher.new('aes-256-cbc')
# STEP 2... generate a random salt
#
# (The salt) is a public value that can be safely stored along with the
# password (e.g. if PBKDF2 is used for password storage). For maximum
# security, a fresh, random salt should be generated for each stored
# password.
salt = OpenSSL::Random.random_bytes(8)
# puts "\nRandom #{salt.size}-byte salt…"
# puts Base64.encode64(salt)
# STEP 3... given the secret (ie. password) and salt, generate a key
#
# The secret to be external to the application
# (eg. in the application.yml, environment variable or similar)
key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret, salt, 20000, cipher.key_len)
# puts "\nGenerated #{key.size}-byte key…"
# puts Base64.encode64(key)
# STEP 4... set to encryption mode, assign the key and generate a random IV
cipher.encrypt
cipher.key = key
iv = cipher.random_iv
# puts "\nRandom #{iv.size}-byte initialization vector…"
# puts Base64.encode64(iv)
# STEP 5... encrypt the data
encrypted = cipher.update(data) + cipher.final
# STEP6... base64 encode and join salt, iv and (encrypted) data
encoded = [salt, iv, encrypted].collect { |bytes| Base64.strict_encode64(bytes) }.join('|')
puts "\n#{cipher.name} encrypted…"
puts encoded
######################################################################
#
# SYMMETRIC DECRYPTION
#
# STEP 1... construct cipher
decipher = OpenSSL::Cipher.new(cipher.name)
# STEP 2... split and base64 decode salt, iv and data
salt, iv, decoded = encoded.split('|').collect { |text| Base64.strict_decode64(text) }
# STEP 3... set to decryption mode and assign the key and iv (decoded previously)
decipher.decrypt
decipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret, salt, 20000, cipher.key_len)
decipher.iv = iv
# STEP 4... decrypt the data
plain = decipher.update(decoded) + decipher.final
puts "\n#{cipher.name} decrypted…"
puts plain
######################################################################
#
# VERIFY SYMMETRIC ENCRYPTION DECRYPTION
#
puts "\n#{cipher.name} decryption #{data == plain ? 'SUCCESSFUL' : 'FAILED'}\n\n"
end
if tests.include? :rsa
# load private key from PEM
private_key = OpenSSL::PKey::RSA.new <<END_PEM
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
END_PEM
public_key = private_key.public_key
# puts "\nPublic key…"
# puts public_key.to_s
modulus = public_key.n.to_s(2)
exponent = public_key.e.to_s(2)
builder = Builder::XmlMarkup.new(target:STDOUT, indent: 2)
puts "\nPublic key (XML)…"
builder.RSAKeyValue { |b| b.Modulus Base64.strict_encode64(modulus); b.Exponent Base64.strict_encode64(exponent) }
puts
encrypted = public_key.public_encrypt data
encoded = Base64.strict_encode64 encrypted
puts "\nRSA (public) encrypted…"
puts encoded
decoded = Base64.strict_decode64 encoded
plain = private_key.private_decrypt decoded
puts "\nRSA (private) decrypted…"
puts plain
puts "\nRSA decryption #{data == plain ? 'SUCCESSFUL' : 'FAILED'}\n\n"
# 2048 / 8 - 11 = 245
data = SecureRandom.random_bytes(245)
encrypted = public_key.public_encrypt data
encoded = Base64.strict_encode64 encrypted
decoded = Base64.strict_decode64 encoded
plain = private_key.private_decrypt decoded
puts "\nRSA decryption #{data == plain ? 'SUCCESSFUL' : 'FAILED'}\n\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment