The following function works perfect in PHP. How can it be translated in Ruby on Rails.
Please note that both privateKey and iv are 32 characters long.
mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $privateKey, base64_decode($enc), MCRYPT_MODE_CBC, $iv)
I tried to use the following in Ruby but got a bad decrypt error.
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.decrypt
cipher.key = privateKey
cipher.iv = iv
decrypted = '' << cipher.update(encrypted) << cipher.final
Here some code which works for me :
def decrypt_data(data, pwd, iv)
encrypted_data = Base64.decode64(data)
aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.decrypt
aes.key = Digest::MD5.hexdigest(pwd)
aes.iv = iv
result = aes.update(encrypted_data) + aes.final
end
In my example the password is encrypted with MD5.
I hope this help
You are base64 decoding it in the php example. Are you doing that in the ruby one as well?
require "base64"
Base64.decode64(encrypted)
Other than that, the code looks right to me.
Related
I'm trying to use AES encryption in order to encrypt files that are being saved on MongoDB.
This uses the GridFS gem.
The AES key is being encrypted itself by RSA and then stored alongside the document within Mongo.
I was previously using Mongoid::EncryptedFields.cipher.encrypt which worked fine, however, the client wanted RSA keys to be used.
My xsl_action:
tempFile = params[:stylesheet].tempfile
file = File.open(tempFile)
grid_fs = Mongoid::GridFS
#Encryption
pub_file = CaseCenter::Config::Reader.get('pub_key');
public_key = OpenSSL::PKey::RSA.new(File.read(pub_file))
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.encrypt
key = cipher.random_key
encData = cipher.update(File.read(file))
#End Encryption
File.open(file, 'wb') do |f|
f.write(encData)
end
encrypted_aes = Base64.encode64(public_key.public_encrypt(key))
stylesheet.aes_key = encrypted_aes
grid_file = grid_fs.put(file.path)
stylesheet.stylesheet_id = grid_file.id
To decrypt the file, I use this:
grid_fs = Mongoid::GridFs
f = grid_fs.get(stylesheet_id)
#Decryption
key = CaseCenter::Config::Reader.get('priv_key')
passphrase = CaseCenter::Config::Reader.get('key_pass')
if key.include? "-----BEGIN RSA PRIVATE KEY-----"
private_key = OpenSSL::PKey::RSA.new(key,passphrase)
else
private_key = OpenSSL::PKey::RSA.new(File.read(key),passphrase)
end
decKey = private_key.private_decrypt(Base64.decode64(doc[:aes_key]))
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.decrypt
cipher.key = decKey
decData = cipher.update(f.data)
The AES key and file are properly encrypted, however, on decryption, the file loses the last 30 characters.
Am I doing something wrong during encryption?
EDIT 1:
Thought it could have been that I hadn't included cipher.final.
I have now included
encData << cipher.final
I am still having the same issue, not all of the file is being returned, however, there are less missing characters now.
I now assume this issue is due to the initial encryption stage.
For anyone else who might experience the same issue, I had forgotten to include cipher.final on both encryption and decryption.
#Encryption
encData << cipher.final
#Decryption
decData << cipher.final
This solved my issue.
I'm sending a value to the client that I want encrypted (and decrypted if/when received back).
It is not super sensitive data, I just don't want to send it in plain naked text.
I know of ActiveSupport::MessageEncryptor but it seemingly requires too many steps for my basic need. Perhaps I'm overthinking it and there's no heavy computation involved under the hood but I'm intuitively looking for something more like how setting/reading a signed cookie works.
It would be a great advantage if I wouldn't need to include anything more than what comes out of the box with Rails 4.
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].
Using Cipher which comes included in ruby # OpenSSL seems simple.
Try this on irb:
require "openssl"
data = "Very, very confidential data"
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
encrypted = cipher.update(data) + cipher.final
decipher = OpenSSL::Cipher::AES.new(128, :CBC)
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.update(encrypted) + decipher.final
puts data == plain
How to encrypt and decrypt the url using blowfish in ruby?
ex: url= http://localhost:3000?username=vam&paswd=1234&street=hyd&contact=999999999&company=raymarine&city=hyd&state=UP&country=ZP&zip_code=543211
Shamelessly stolen and adapted, this appears to be what you want.
require 'rubygems'
require 'crypt/blowfish'
require 'base64'
plain = "http://localhost:3000?username=vam&paswd=1234&street=hyd&contact=999999999&company=raymarine&city=hyd&state=UP&country=ZP&zip_code=543211"
puts plain
blowfish = Crypt::Blowfish.new("A key up to 56 bytes long")
enc = blowfish.encrypt_string(plain)
mimed = Base64.encode64(enc)
puts mimed
$ ruby blowfish.rb
http://localhost:3000?username=vam&paswd=1234&street=hyd&contact=999999999&company=raymarine&city=hyd&state=UP&country=ZP&zip_code=543211
K9XLp7LmidHZnhQi1i93Lfi1qV4pWFzksnOkNDt/VqyWdZ0OA+K+0soWl7OZ
bNOi17OLIkjhMzHx4Av+h1SL7GP9aletclQGO6XoW2Cge0JweChlj3HXjZT1
fQ6WIqw0zVRaWmqvk1sTqKgvNhy7XPS99RPuX8JdVP87rreklam2LJC97sPh
pu5W9U/lhW7VeRm1HgbI+M0=
Of course, if you need the encrypted contents to serve as an URL, then prepend http://localhost:3000/foo?q= to the encrypted contents, and provide a /foo/q GET handler that can decrypt the string and do whatever it is you need to do with it.
The Crypt library does not work for Ruby 1.9 and later. You can use this gist instead. It requires no gems:
https://gist.github.com/kajic/5686064
url = 'http://localhost:3000?username=vam&paswd=1234&street=hyd&contact=999999999&company=raymarine&city=hyd&state=UP&country=ZP&zip_code=543211'
encrypted_url = Cipher.encrypt_base64('your secret key', url)
This is a C# code:
byte[] pb = System.Text.Encoding.UTF8.GetBytes(policy.ToString());
// Encode those UTF-8 bytes using Base64
string policyB = Convert.ToBase64String(pb);
// Sign the policy with your Secret Key using HMAC SHA-1.
System.Security.Cryptography.HMACSHA1 hmac = new System.Security.Cryptography.HMACSHA1();
hmac.Key = System.Text.Encoding.UTF8.GetBytes(secretKey);
byte[] signb = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(policyB));
string signature = Convert.ToBase64String(signb);
How to do the same in Ruby on rails? More specifically I need to know functions to get bytes from string and base64 encode them and calculate hmac hash.
Not sure if it exactly the same, but it works for me:
#policy = ActiveSupport::Base64.encode64s(#policy)
# Sign policy with secret key
digest = OpenSSL::Digest::Digest.new('sha1')
#signature = ActiveSupport::Base64.encode64s(OpenSSL::HMAC.digest(digest, secretKey, #policy))
I'll try again.
There are a couple of HMAC libraries for ruby/rails that might make this much simpler:
http://auth-hmac.rubyforge.org/
My RoR server receives a string, that was encrypted in C++ application using des3 with base64 encoding
The cipher object is created so:
cipher = OpenSSL::Cipher::Cipher::new("des3")
cipher.key = key_str
cipher.iv = iv_str
key_str and iv_str: are string representations of key and initialization vector for encryption algorithm. They are the same for RoR and C++ application.
The code on the RoR side is following:
result = ""
result << cipher.update( Base64.decode64(message) )
result << cipher.final
After executing the last line of code, i get an exception
OpenSSL::CipherError (bad decrypt)
What is wrong here ? Any ideas ?
The documentation for OpenSSL::Cipher states:
Make sure to call .encrypt or .decrypt before using any of the following
methods:
[key=, iv=, random_key, random_iv, pkcs5_keyivgen]
In your specific case, omitting the call to cipher.decrypt causes a bad decrypt error, as you've seen.
The following example corrects that problem and exhibits the expected behavior:
require 'openssl'
require 'Base64'
# For testing purposes only!
message = 'MyTestString'
key = 'PasswordPasswordPassword'
iv = '12345678'
# Encrypt plaintext using Triple DES
cipher = OpenSSL::Cipher::Cipher.new("des3")
cipher.encrypt # Call this before setting key or iv
cipher.key = key
cipher.iv = iv
ciphertext = cipher.update(message)
ciphertext << cipher.final
puts "Encrypted \"#{message}\" with \"#{key}\" to:\n\"#{ciphertext}\"\n"
# Base64-encode the ciphertext
encodedCipherText = Base64.encode64(ciphertext)
# Base64-decode the ciphertext and decrypt it
cipher.decrypt
plaintext = cipher.update(Base64.decode64(encodedCipherText))
plaintext << cipher.final
# Print decrypted plaintext; should match original message
puts "Decrypted \"#{ciphertext}\" with \"#{key}\" to:\n\"#{plaintext}\"\n\n"
gem install encryptor
It wraps the standard Ruby OpenSSL library and allows you to use any of its algorithms.
require 'encryptor'
Base64.decode64(message).decrypt(:algorithm => 'des', :key => key, :iv => iv)