duansha7453 2011-04-06 16:42
浏览 64
已采纳

在php中使用Ruby sha512密码检索

(Updated due to some confusion over my question) We use this method to generate a digested_password, which is saved to our database for later lookup. When we authenticate a user to our application, this method is again ran against their input and if the digested_password output matches the digested_password we saved in the database we authenticate them. I need to reproduce this function in PHP for another application that shares the database.

def self.hash_password( password, salt )
  salted_password = password.insert 4, salt
  digested_password = Digest::SHA512.hexdigest("#{salted_password}")
  return digested_password
end

I really have no experience with Ruby so please forgive my lack of understanding.

Thanks!

  • 写回答

4条回答 默认 最新

  • duanpiangeng8958 2011-04-06 16:55
    关注

    Because you can't "retrieve" a password from a one-way hash like SHA-512, the closest we can get is being able to generate the same hash from the same password and salt. Let's look at the Ruby code:

    def self.hash_password( password, salt )
      salted_password = password.insert 4, salt
      digested_password = Digest::SHA512.hexdigest("#{salted_password}")
      return digested_password
    end
    

    The only thing a bit "weird" here is the call to the .insert method on the password string. It's basically splicing the salt right into the password, starting at the fourth character index. Normally salts are simply concatenated with the password.

    We can replicate this using substr:

    function hash_password($password, $salt) {
        $salted_password = substr($password, 0, 4) . $salt . substr($password, 4);
        return hash('sha512', $salted_password);
    }
    

    I'm using the now-default hash extension here, as it's pretty much the most reliable way to generate a SHA-512 hash.

    Using this code, you should be able to generate identical hashes for a given identical password and salt combination. I'm not sure what the behavior would be when the password is less than five characters long.


    Yup, looks like it should work:

    [charles@lobotomy ~]$ irb
    irb(main):001:0> require 'digest/sha2'
    => true
    irb(main):002:0> def hash_password( password, salt )
    irb(main):003:1>   salted_password = password.insert 4, salt
    irb(main):004:1>   digested_password = Digest::SHA512.hexdigest("#{salted_password}")
    irb(main):005:1>   return digested_password
    irb(main):006:1> end
    => nil
    irb(main):007:0* puts hash_password('password', 'salt')
    92d3efdbf51d199b0930c427b77dc8d5cf41ac58b6fab5f89cc3f32d719a8f6ffcdff6211bdd0565a6e7b09925839e5dcce1fa5abf65eca87c6a883ab0b510b9
    => nil
    irb(main):018:0> exit
    [charles@lobotomy ~]$ 
    [charles@lobotomy ~]$ php -a
    Interactive shell
    
    php > function hash_password($password, $salt) {
    php {     $salted_password = substr($password, 0, 4) . $salt . substr($password, 4);
    php {     return hash('sha512', $salted_password);
    php { }
    php > echo hash_password('password', 'salt');
    92d3efdbf51d199b0930c427b77dc8d5cf41ac58b6fab5f89cc3f32d719a8f6ffcdff6211bdd0565a6e7b09925839e5dcce1fa5abf65eca87c6a883ab0b510b9
    php >
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • dongmen1860 2011-04-06 16:48
    关注

    SHA512 is a one way hash function, meaning that you can't easily get the input for any given output.

    It is possible, but very expensive, to build a rainbow table. Because this is a salted hash, it's even more difficult

    评论
  • dsubq24666 2011-04-06 17:11
    关注
    function hash_password($password, $salt)
    {
      $salted_password = substr_replace($password, $salt, 4, 0);
      $digested_password = hash('sha512', $salted_password);
      return $digested_password;
    }
    
    评论
  • douping1581 2011-04-06 17:12
    关注

    I figured it out. I didn't quite understand the insert method in Ruby, and it turns out the salt is being inserted into the password at the fourth character. Here is the PHP equivalent:

    $password_input = "derpaderp";
    $password_salt = "aderp";
    $arg=substr_replace($password_input, $password_salt, 4, 0);
    $pass = hash('sha512', $arg);
    if ( $digested_password_from_database == $pass ){ echo "success!"; }
    

    Thanks for your replies folks.

    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 Tpad api账户 api口令
  • ¥30 ppt进度条制作,vba语言
  • ¥15 stc12c5a60s2单片机测光敏ADC
  • ¥15 生信simpleaffy包下载
  • ¥15 请教一下simulink中S函数相关问题
  • ¥15 在二层网络中,掩码存在包含关系即可通信
  • ¥15 端口转发器解析失败不知道电脑设置了啥
  • ¥15 Latex算法流程图行号自定义
  • ¥15 关于#python#的问题:我在自己的电脑上运行起来总是报错,希望能给我一个详细的教程,(开发工具-github)
  • ¥40 基于51单片机实现球赛计分器功能