Created
July 7, 2015 13:29
-
-
Save sbfaulkner/2433e27dc595d3e0db98 to your computer and use it in GitHub Desktop.
cryptography tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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