Ruby bcrypt非盐密码比较

时间:2017-01-02 01:07:45

标签: ruby sinatra bcrypt

我对bcrypt密码哈希检索和比较感到困惑。它们确实是平等的,但比较结果是错误的。顺便说一下,我使用的是Sinatra,而不是RAILS。

我的代码中含有盐,但我甚至无法使用盐。我不明白这里有什么不对,因为它的所有输出都是等价的。

    require 'pg'
    require 'bcrypt'

    pw = 'trump_hairs'
    # salt = 'grains'           # not used for this trial

    # salty = pw + salt
    # salted = BCrypt::Password.create(salty)   
    hashed = BCrypt::Password.create(pw)    
    # p salted
    conn = PG.connect( dbname: 'alphaDB' )

    if true
        @res = conn.exec_params( 
            %q{ INSERT INTO USERS ( username, password, email, status) VALUES($1, $2, $3, $4) },
            ['peter', hashed, 'peter@gmail.com', 'on'] )
    end

    ######## this record works out just fine.  pw is a text field

    @res = conn.exec_params(
        %q{ SELECT password FROM users WHERE username = $1 },
        ['peter']   )
    r = @res.getvalue(0,0)

    puts BCrypt::Password.new(r)
    held = BCrypt::Password.new(r)
    p held
    p held.equal? hashed
    puts (hashed == held ? "success" : hashed)

我创建密码并输入带有硬编码字段和散列密码的记录。然后我为相同的用户名执行SELECT(没有重复项,因此它是唯一的)(INSERT上的布尔值允许我关闭重复SELECT试验的INSERT),我得到相同的密码哈希。

然后一切都崩溃了。它不会与真实相比。我不知道为什么。我以为它是真的。我没有过去的部分来自bcrypt文档:

my_password = BCrypt::Password.new("$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa")
my_password == "trump_hairs"     #=> true (my password inserted here)

我遗漏了一些东西,并且想要实施盐。干杯

2 个答案:

答案 0 :(得分:3)

实际上BCrypt :: Password会覆盖==方法。所以在你的代码中,hold == pw line返回true,因为它调用BCrypt' s == method。当你使用pw ==持有Ruby时,使用String' s ==方法返回false。

按顺序,如果要检查哈希值是否有效。您必须使用左侧的BCyrpt :: Password对象。

答案 1 :(得分:0)

经过进一步调查,BCrypt :: Password方法和父方法会返回不同的结果:

    require 'bcrypt'

    @res = conn.exec_params(
        %q{ SELECT password FROM users WHERE username = $1 },
        ['peter']   )
    r = @res.getvalue(0,0)
    puts "r:" + r

    held = BCrypt::Password.new(r)      # Password
    puts "held: " + held
    puts held == pw                     # => true
    puts pw == held                     # => false
    puts held.eql?(pw)              # => false
    puts pw.eql?(held)              # => false
    puts held.equal?(pw)            # => false
    puts pw.equal?(held)            # => false
    puts held != pw                     # => false
    puts held === pw                    # => false
    puts
    puts held.inspect                   # => "$2a$10$mmTIpDHa9VZDrYZpRj9.x.R1/ihCEcjqwQZQbHsFwnn/tzDHtd9x6"

结果:

    r:$2a$10$mmTIpDHa9VZDrYZpRj9.x.R1/ihCEcjqwQZQbHsFwnn/tzDHtd9x6
    held: $2a$10$mmTIpDHa9VZDrYZpRj9.x.R1/ihCEcjqwQZQbHsFwnn/tzDHtd9x6
    true
    false
    false
    false
    false
    false
    false
    false

    "$2a$10$mmTIpDHa9VZDrYZpRj9.x.R1/ihCEcjqwQZQbHsFwnn/tzDHtd9x6"

所以我把它发布到Github并注意到必须遵守第一个比较器。