Last active
August 29, 2015 14:05
-
-
Save ronny/147dfaf878c8d0e58c26 to your computer and use it in GitHub Desktop.
AES symmetric-key encryption/decryption in Ruby with the built-in OpenSSL lib
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
require 'openssl' | |
require 'digest/sha2' | |
module AESCrypt | |
CIPHER_TYPE = "AES-256-CBC".freeze | |
class << self | |
def decrypt(armored_iv_and_ciphertext, key) | |
ciphertext = [armored_iv_and_ciphertext].pack("H*") | |
aes = OpenSSL::Cipher::Cipher.new(CIPHER_TYPE) | |
aes.decrypt | |
aes.key = Digest::SHA512.hexdigest(key) | |
aes.iv = ciphertext.slice!(0, 16) | |
aes.update(ciphertext) + aes.final | |
end | |
def encrypt(data, key) | |
aes = OpenSSL::Cipher::Cipher.new(CIPHER_TYPE) | |
aes.encrypt | |
aes.iv = iv = aes.random_iv | |
aes.key = Digest::SHA512.hexdigest(key) | |
iv_and_ciphertext = iv + aes.update(data) + aes.final | |
armored_iv_and_ciphertext = iv_and_ciphertext.unpack("H*")[0] | |
end | |
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
RSpec.describe AESCrypt do | |
describe 'encrypt' do | |
let(:key) { "woohoosecret" } | |
let(:plaintext) { "its private" } | |
it 'returns a non-nil string other than plaintext or the key' do | |
result = AESCrypt.encrypt(plaintext, key) | |
expect(result).not_to be_nil | |
expect(result).to be_a String | |
expect(result).not_to match plaintext | |
expect(result).not_to match key | |
end | |
end | |
describe 'decrypt' do | |
let(:key) { "woohoosecret" } | |
let(:plaintext) { "its private" } | |
it 'works' do | |
result = AESCrypt.decrypt(AESCrypt.encrypt(plaintext, key), key) | |
expect(result).to eq plaintext | |
end | |
end | |
end |
@fullofcaffeine The armored_iv_and_ciphertext
is not about security, it's making the encryption output more easily transportable (e.g. over the wire, serialised to a file, database,etc.), it'd simply be an ASCII string of hex characters, no binary bytes to worry about.
I'm by no means an expert in cryptography, so I'm not going to pretend to be one :) It does sound like using OpenSSL::PKCS5.pbkdf2_hmac_sha1
instead of Digest::SHA512.hexdigest
may be better, but I'm not sure.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Interesting! Could you elaborate on the additional armored_iv_and_ciphertext? I'm wondering if iv_and_ciphertext would be enough for my purposes. Why did you add this step? How much more security does it add in terms of hacking effort? And lastly, why didn't you use a PKCS5 (OpenSSL::PKCS5.pbkdf2_hmac_sha1) to generate the key?