Ruby on Rails Decryption

Encrypt, decrypt using Rails

You mean this one?: ActiveSupport::MessageEncryptor. Here is the way to reuse Rails 5+ on Ruby 2.4+ application's secret:

crypt = ActiveSupport::MessageEncryptor.new(Rails.application.secrets.secret_key_base[0..31])
encrypted_data = crypt.encrypt_and_sign('my confidental data')

And encrypted data can be decrypted with:

decrypted_back = crypt.decrypt_and_verify(encrypted_data)

The above example uses first 32 characters of Rails app secret as an encryption and signing key, because the default MessageEncryptor cipher aes-256-gcm requires exactly 256 bit key. By convention, during the app creation, Rails generates a secret as a string of 128 hex digits.

Important! Ruby 2.4 upgrade note

Before Ruby 2.4 and Rails 5 there was no key size restriction and it was popular to just past full secret into the encryptor initializer:

# pre-2.4
crypt = ActiveSupport::MessageEncryptor.new(Rails.application.secrets.secret_key_base)

Internally the encryption algorithm (AES256GCM provided by OpenSSL) was using only 32 characters from the key, however the signing algorithm (SHA1) was consuming all 128 characters.

Therefore, while upgrading an app from pre-2.4 Ruby, and where the app previously encrypted the data with an unrestricted key size, the MessageEncryptor must get a full secret in the second parameter to avoid ActiveSupport::MessageVerifier::InvalidSignature on the legacy data decryption:

# post-2.4 upgrade
crypt = ActiveSupport::MessageEncryptor.new(Rails.application.secrets.secret_key_base[0..31], Rails.application.secrets.secret_key_base)

Rails - decrypt attr_encrypted manually

We can simply use the advantage of decrypt method.

Contact.decrypt_#{encrypted_column_name}(encrypted_value, key: encryption_key)

In my case it has to be

Contact.decrypt_email(encrypted_email, key: encryption_key)

So every time inside my loop, instead of calling

contact.email (which will call query to fetch encryption key), I will simply call decrypt method with the encryption_key that is already cached. 

Easiest and fastest way to encrypt/decrypt in Rails?

Why not put it in the session? Then it will be part of the encrypted cookie / in your session store.

You can set the value with session[:message] = "my message" and get it with session[:message].

Java encryption / decryption to Ruby

You need to use the IV and Key from your Java Example, not a new/random IV/Key:

require "openssl"
require "base64"
require 'byebug'

include Base64

plain_text = "abceeffslaj"

key = 'Bar12345Bar12345'
iv = 'RandomInitVector'

cipher = OpenSSL::Cipher::AES128.new(:CBC)
cipher.encrypt
cipher.key = key
cipher.iv = iv
cipher_text = cipher.update(plain_text) + cipher.final

cipher = OpenSSL::Cipher::AES128.new(:CBC)
cipher.decrypt
cipher.key = key
cipher.iv = iv
decrypted_plain_text = cipher.update(cipher_text) + cipher.final

puts "AES128 in CBC mode"
puts "Key: " + urlsafe_encode64(key)
puts "Iv: " + urlsafe_encode64(iv)
puts "Plain text: " + plain_text
puts "Cipher text: " + urlsafe_encode64(cipher_text)
puts "Decrypted plain text: " + decrypted_plain_text


Related Topics



Leave a reply



Submit