且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Ruby中生成密码,就像在Ruby on Rails中的Devise Gem一样

更新时间:2022-10-14 23:35:10

设计代码如下:

  def self.digest (密码,拉伸,盐,胡椒)
:: BCrypt :: Engine.hash_secret(#{password}#{pepper},salt,stretch)
end

您可以在PHP中查看如何使用bcrypt在如何在PHP中使用bcrypt进行哈希密码?



由默认情况下,Devise使用10段。



盐看起来是加密密码的前29个字符。您可以(在rails中) User.first.authenticable_salt



胡椒应列在 config / initializers / devise.rb ,但它可能会使用您的应用程序秘密令牌。



请参阅 https://github.com/plataformatec/devise/blob/master/lib/devise/models /encryptable.rb


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 :-)

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