Created
July 12, 2017 17:13
-
-
Save boykoc/e4795e456d0e983f4f10b73c807331a4 to your computer and use it in GitHub Desktop.
Ruby OpenSSL Symmetric Encryption and Decryption.
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
# Get the encryption classes needed. Assuming they are in the same directory. | |
require './symmetric_encrypt.rb' | |
require './symmetric_decrypt.rb' | |
puts "What would you like to do?" | |
puts "Type 'encrypt', 'decrypt' or 'exit'." | |
input = gets.chomp | |
input.downcase | |
if input == 'encrypt' | |
puts "Enter the file name, extension and path encrypt" | |
file = gets.chomp | |
puts "Enter a super hard password and remember it, you'll need it again to see the file contents" | |
password = gets.chomp | |
e = SymmetricEncrypt.new(file, password) | |
e.encrypt | |
e.remove_file | |
puts "Done." | |
exit | |
elsif input == 'decrypt' | |
puts "Enter the file name, extension and path to decrypt" | |
file = gets.chomp | |
puts "Enter a super hard password *that you used to encrypt the file*" | |
password = gets.chomp | |
d = SymmetricDecrypt.new(file, password) | |
d.decrypt | |
d.remove_file | |
puts "Done." | |
exit | |
elsif input == 'exit' | |
exit | |
end |
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
class SymmetricDecrypt | |
require 'openssl' | |
require 'base64' | |
attr_reader :file, :password | |
def initialize(file, password) | |
@file = file | |
@password = password | |
end | |
## | |
# Decrypt the file given during instantiation using | |
# a symmetric key. | |
def decrypt | |
cipher = OpenSSL::Cipher.new 'AES-128-CBC' | |
cipher.decrypt | |
# Get the initialization vector from the encrypted file and decode from base64. | |
cipher.iv = Base64.decode64(File.read(file).each_line.take(1).last.chomp) | |
pwd = password | |
# Get the SALT from the encrypted file and decode from base64. | |
salt = Base64.decode64(File.read(file).each_line.take(2).last.chomp) | |
iter = 20000 | |
key_len = cipher.key_len | |
digest = OpenSSL::Digest::SHA256.new | |
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest) | |
cipher.key = key | |
decrypted = "" | |
# Decrypt each line in the original file. | |
File.foreach(file).with_index do |line, index| | |
# Skip the first 2 lines (the IV and SALT). | |
next if index < 2 | |
decrypted << cipher.update(line) | |
end | |
decrypted << cipher.final | |
# Strip out the .enc filetype. | |
output_file = file.gsub('.enc', '') | |
# Write the decrypted information to a new file. | |
File.open(output_file, 'w') do |f| | |
f.write(decrypted) | |
end | |
end | |
## | |
# Remove original file. | |
def remove_file | |
File.delete file | |
end | |
end |
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
class SymmetricEncrypt | |
require 'openssl' | |
require 'base64' | |
attr_reader :file, :password | |
def initialize(file, password) | |
@file = file | |
@password = password | |
end | |
## | |
# Encrypt the file given during intantiation using | |
# a symmetric key. | |
def encrypt | |
cipher = OpenSSL::Cipher.new 'AES-128-CBC' | |
cipher.encrypt | |
# Use a random initialization vector each time | |
# a file is encrypted. | |
iv = cipher.random_iv | |
pwd = password | |
# Use a random salt each time a file is encrypted. | |
salt = OpenSSL::Random.random_bytes 16 | |
iter = 20000 | |
key_len = cipher.key_len | |
digest = OpenSSL::Digest::SHA256.new | |
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest) | |
cipher.key = key | |
# Create an encrypted version of the file. Include the IV and SALT | |
# to recreate symmetric key when decrypting. | |
File.open("#{file}.enc", 'w') do |f| | |
# Base64 encode IV and SALT to prevent encoding issues. | |
# These are publicly sharable. The important part is to not | |
# share the password used to create the key, and to use | |
# random values for the IV and SALT. Basically, don't share the key | |
# publicly/with the data in transit. The sender and reciever need the key only. | |
# If it's always the same it'll be easier to eventually figure out the key. | |
f.write Base64.encode64(iv) | |
f.write Base64.encode64(salt) | |
encrypted = cipher.update File.read(file) | |
encrypted << cipher.final | |
f.write encrypted | |
end | |
end | |
## | |
# Remove original file. | |
def remove_file | |
File.delete file | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment