Ruby/Rails: How to get same encrypted value every time we encrypt a particular string
Asked Answered
C

3

6

Does ActiveSupport::MessageEncryptor support deterministic encryption so that we get the same encrypted value every time we encrypt a particular string? If not, are there any other Ruby libs that support deterministic encryption?

My goal is to get same encrypted value every time I encrypt a string and I should be able to decrypt it to original value as well.

Thanks.

Calcium answered 26/2, 2018 at 18:32 Comment(1)
Try this for string encrypt and decrypt gist.github.com/wteuber/5318013Acicular
B
8

You get different crypts because ActiveSupport::MessageEncryptor uses OpenSSL for encryption which requires an iv by default to prevent attackers from inferring relationships between segments of the encrypted message. I would highly recommend you to not mess around with that because you open ways for attackers to infer the encryption key.

However if you still want to do that take a look into the OpenSSL documentation of ruby. There should be a way to encrypt without vector.

Because it's a high security risk I don't add code to the answer to protect others from unnecessary loop holes.

Belldame answered 26/2, 2018 at 19:42 Comment(3)
Tobias, thanks for your note and I understand the security risk. The information we are trying to encrypt is stored in a secure database. We need to use the encrypted column in WHERE clause to filter encrypted data. We have discussed the security concerned and we are okay with this approach. I would be obliged if you could share a code snippet and maybe delete it later once I take a lot? Thanks again.Calcium
@Calcium may I ask which database engine you use? What if you hash the content instead?Belldame
its MySQL - InnoDB. We are also planning to migrate to Postgres in near future.Calcium
G
4

I did not get why ActiveSupport:MessageEncryptor didn't work. Here is another way to do it.

require 'bcrypt'

encrypted_password = BCrypt::Engine.hash_secret('password@!2#4', 'ADD SALT HERE')

you can also use it like this:

class User
  SALT = 'GENERATE A STATIC SALT HERE AND KEEP IT SECURE'.freeze
  include BCrypt

  def password=(given_password)
    @encrypted_password = Engine.hash_secret(given_password, SALT)
  end
end

For the full documentation please check their repo

PS: using a static salt for all users for authentication is a bad idea.

Guay answered 26/2, 2018 at 19:48 Comment(5)
BCrypt produces the different encrypted value every time we call Password.create("something_to_encrypt").Calcium
I updated the answer to use a static salt which assures the same encryption (this is used by devise in authentication)Guay
Thank you, Khaled. What I am actually trying to do is to store the encrypted auth_tokens in the database. The encryption part is working now. Now there is another issue, the problem is it's not logging me in even after even if we authenticate it properly in authenticate_user_from_token! method. It creates the session entry in the database but gets me to the login page. Do you have any idea where I need to look at?Calcium
Can you maybe share some code about this? Maybe even another question (A)Guay
Khaled, I have posted another question: #48999422Calcium
I
-1

Of course: one just need to use the same key to get the same encryption

x = ActiveSupport::MessageEncryptor.new('12345678901234567890123456789012').encrypt_and_sign('foo')
=> "bXJmRUczdjVXRFdLTitUcmkvRnk1UT09LS0vb2ZYdDRybGdWbmNXMUI1VDNnQzVBPT0=--13232bbe31d966f7d1df3aaa6fcc1cdc9eea60a1"
ActiveSupport::MessageEncryptor.new('12345678901234567890123456789012').decrypt_and_verify(x)
=> "foo"

It's hard to tell why you get different results since you didn't post any code...

Insphere answered 26/2, 2018 at 18:51 Comment(4)
try to invoke x = ActiveSupport::MessageEncryptor.new('12345678901234567890123456789012').encrypt_and_sign('foo') multiple times and you would see it different encrypted value every time. I need same encrypted value every time I encrypt the same string with the same key.Calcium
But if you store the encrytped value, and try to decrypt it - it should give you the decrypted value. Did you try it?Insphere
Yes, it decrypts fine. What's I want is consistent/same encrypted value every time I encrypt a string.Calcium
Ok, got it. Maybe this will be useful for you #4129439 But I wonder - why would you insist on this, since it makes it less secure?Insphere

© 2022 - 2024 — McMap. All rights reserved.