Rails Encryption/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)

Ruby: file encryption/decryption with private/public keys

Note Well: As emboss mentions in the comments, this answer is a poor fit for an actual system. Firstly, file encryption should not be carried out using this method (The lib provides AES, for example.). Secondly, this answer does not address any of the wider issues that will also affect how you engineer your solution.

The original source also goes into more details.

Ruby can use openssl to do this:

#!/usr/bin/env ruby

# ENCRYPT

require 'openssl'
require 'base64'

public_key_file = 'public.pem';
string = 'Hello World!';

public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file))
encrypted_string = Base64.encode64(public_key.public_encrypt(string))

And decrypt:

#!/usr/bin/env ruby

# DECRYPT

require 'openssl'
require 'base64'

private_key_file = 'private.pem';
password = 'boost facile'

encrypted_string = %Q{
...
}

private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file),password)
string = private_key.private_decrypt(Base64.decode64(encrypted_string))

from here

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].

Encryption-Decryption in Rails

SHA1 is a one way function you can't reverse it.

This may be of interest re password resets:
http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/

If you want to do encryption/decryption then you should use something like AES. Once you start using encryption/decryption, however, you'll also have to start worrying about key management too.

Regarding your comment to the OP below - if you are going to to be storing CC info, I would advise you get a security person in who knows about crypto, key management etc and who also understands the relevant legal and regulatory aspects.

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