Reputation: 1
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:
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"
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
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
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