8

Hey so I was using Rails for my app but now I'm migrating to ReactJs + Node.

I cannot discover how Devise encrypted the password so I can send the request from my frontend to my backend.

I'm using Postgres for my db.

Jared Forth
  • 1,577
  • 6
  • 17
  • 32
Gonzalo4488
  • 439
  • 1
  • 5
  • 14

2 Answers2

7

Devise is using bcrypt gem for encryption (https://github.com/codahale/bcrypt-ruby), you can also look at how Devise is doing it here: https://github.com/plataformatec/devise/blob/f39c6fd92774cb66f96f546d8d5e8281542b4e78/lib/devise/encryptor.rb

For more details on the algorithm, you can look here: https://github.com/codahale/bcrypt-ruby/blob/master/lib/bcrypt/password.rb

Hope that helps

The Lazy Log
  • 3,564
  • 2
  • 20
  • 27
  • Hey! It helped a little, I installed bcrypt and is kind of working because it doesn't give me the exact same encrypted_password. Is this because Devise uses some kind of salt? Thanks for the help!. – Gonzalo4488 Apr 01 '18 at 18:56
  • Yes, probably. You have to look at the way Devise is using the algorithm and do a similar thing in your own version – The Lazy Log Apr 02 '18 at 14:58
  • @TheLazyLog I wanted to validate the user(created using ROR devise) using pure python bcrypt lib, is it possible? – RockStar Mar 10 '20 at 10:24
  • @RockStar Yes it is possible. But you need to use the same bcrypt version and the cost factor. You can read more here: https://www.freecodecamp.org/news/how-does-devise-keep-your-passwords-safe-d367f6e816eb/ – The Lazy Log Mar 11 '20 at 03:13
0

Based on the previous answer here is a step-by-step instruction how you can "use" passwords stored with Ruby Devise gem in NodeJs based app.

In your Ruby codebase:

  1. Look for config/initializers/devise.rb file
  2. You should be able to find a line with config.pepper declaration e.g. config.pepper = '24a37cf1ccf5f682fc6f2'
  3. Copy value that is assigned to this property

In your NodeJs codebase:

  1. Install bcrypt package
  2. Compare encrypted passwords saved by Devise in the database using the following code
const bcrypt = require('bcrypt');

// this is what you have copied in previous section, step 3.
const pepper = '24a37cf1ccf5f682fc6f2';

// you should get it probably from user input
const plaintext = 'admin123';

// you should get it from your Devise database table `encrypted_password` column
const encrypted_password = '$2a$12$K0ByB.6YI2/OYrB4fQOYLes9WMlxvjJ8Zgt9U44NEdtmCeGkKvCX2'; 

const equal = bcrypt.compareSync(plaintext + pepper, encrypted_password);

console.log(equal); // if true `plaintext` is equal to what is saved as `encrypted_password`

NOTE: Cost factor and salt used by Devise doesn't matter as those values are saved in DB as part of the encrypted_password string, see How bcrypt.js compare method knows the number of salting rounds? and Do I need to store the salt with bcrypt?)

jmarceli
  • 19,102
  • 6
  • 69
  • 67