user1339860
user1339860

Reputation: 1

How to generate the password in PHP as it did by Devise Gem in Ruby on Rails

I'm renewing a website from Ruby on Rails to PHP. I need to generate the passwords which are generated by Devise Gem in Ruby on Rails. I have to know what is the hashing method for password to create same method with PHP. but it's not easy to find that codes inside the Ruby on Rails as a beginner. If somebody know where should I check to find it, please help me.

These two are all what I found:

1) The configuration of encryptor is disabled in devise.rb like below:
  # config.encryptor = :sha1
2) I read the comments very carefully then I found that they using sha512 and bcrypt as default encryptor.
  # (default), :sha512 and :bcrypt. Devise also supports encryptors from others

I tried to make the same encrypted password in different ways with PHP:

1) sha1('--'.$password_salt.'--'.$encrypted_password);
2) sha1($password_salt.'-----'.$encrypted_password);
3) sha1('--'.$password_salt.'--'.$encrypted_password.'--');
4) sha1($password_salt.$encrypted_password);
5) sha1($encrypted_password.$password_salt);
6) substr(hash('sha512', $password_salt.$encrypted_password, false), 20);
7) substr(hash('sha512', $encrypted_password.$password_salt, false), 0, 40);
8) hash('sha512', $encrypted_password.$password_salt, false);
9) hash('sha512', $password_salt.$encrypted_password, false);
10) substr(hash('sha512', '--'.$password_salt.'--'.$encrypted_password.'--', false), 0, 40);

I couldn't get the same result from any of above. Is there anybody whom could tell me the encryption method of Devise Gem??

HELP ME!!!

ps. I'm not good at English. Even if my English is not correct, please don't be angry.


I'm answering myself:

  1. The Encryptor is Sha1

    I was looking only "devise.rb" in the folder "\config\initializers" The encryptor was commanted as "# config.encryptor = :sha1" But there is one more "devise.rb" inside the Ruby lib folder, "\Ruby191\lib\ruby\gems\1.9.1\gems\devise-1.0.8\lib\devise.rb" There is one more configuration as "@@encryptor = :sha1"

  2. Encryption Method using Sha1 When you go to the file below you will see the codes for algorithm: \Ruby191\lib\ruby\gems\1.9.1\gems\devise-1.0.8\lib\devise\encryptors\sha1.rb

    require "digest/sha1"

    module Devise module Encryptors # = Sha1 # Uses the Sha1 hash algorithm to encrypt passwords. class Sha1 < Base

            # Gererates a default password digest based on stretches, salt, pepper and the
            # incoming password.
            def self.digest(password, stretches, salt, pepper)
                digest = pepper
                stretches.times { digest = self.secure_digest(salt, digest, password, pepper) }
                digest
            end
    
            private
    
            # Generate a SHA1 digest joining args. Generated token is something like
            #     --arg1--arg2--arg3--argN--
            def self.secure_digest(*tokens)
                ::Digest::SHA1.hexdigest('--' << tokens.flatten.join('--') << '--')
            end
    
        end
    end
    

    end

So I translated to PHP

function encrypt_password($salt, $password) {
    $pepper = '';
    $digest = $pepper;
    $stretches = 10;

    for ($i=0; $i<$stretches; $i++) {
        $join = '--'.$salt.'--'.$digest.'--'.$password.'--'.$pepper.'--';
        $digest = Sha1($join);
    }
    $result = substr($digest, 0, 40);
    return $result;
}

it's working very well :-)

Upvotes: 6

Views: 2658

Answers (2)

Gazler
Gazler

Reputation: 84150

The devise code looks like:

 def self.digest(password, stretches, salt, pepper)
   ::BCrypt::Engine.hash_secret("#{password}#{pepper}",salt, stretches)
 end

You can see how to do bcrypt in PHP at How do you use bcrypt for hashing passwords in PHP?

By default, Devise uses 10 stretches.

The salt looks to be the first 29 characters of the encrypted password. You can do (in rails) User.first.authenticable_salt

The pepper should be listed in config/initializers/devise.rb but it may use your application secret token.

Please see https://github.com/plataformatec/devise/blob/master/lib/devise/models/encryptable.rb

Upvotes: 1

GergelyPolonkai
GergelyPolonkai

Reputation: 6421

According to the Devise Gem sources, the method is a bit more complicated. the SHA512 part would look something like this:

function sha512_digest($password, $stretches, $salt, $pepper)
{
    $digest = $pepper;
    for ($i = 0; $i < $stretches; $i++)
    {
        $digest = hash('sha512', '--' . $salt . '--' . $digest . '--' . $password . '--' . $pepper . '--');
    }
}

The BCrypt part is kinda unclear to me, the only thing I figured out so far is that it's a Blowfish encryption.

Upvotes: 0

Related Questions