用bcrypt发生了什么事?

 小妮子831020 发布于 2023-02-03 12:28

这是来自github页面:

require 'bcrypt'

class User < ActiveRecord::Base
  # users.password_hash in the database is a :string
  include BCrypt

  def password
    @password ||= Password.new(password_hash)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end
end

看来要访问密码方法,您需要从create方法中将其作为属性调用:

@user.password = user_params[:password]
@user.save

好的?但现在储存的盐在哪里?我根本就没有得到它,这又如何远程安全?

要检索散列密码,您需要以下方法:

  def password
    @password ||= Password.new(password_hash)
  end

并将其称为属性:

  if @user.password == params[:password]
    give_token
  else
    false
  end

所以看来一切都在没有盐的情况下......它是如何做到的?

这意味着我现在只需要在我的数据库中使用一列来处理密码,对吧?password或者password_hash代替password_salt | password_hash

那么为什么github页面会这样说:

但即使这有弱点 - 攻击者可以通过相同的算法运行可能的密码列表,将结果存储在一个大数据库中,然后通过哈希查找密码:

PrecomputedPassword.find_by_hash().password #=> "secret1"
Salts

然后这就是我真正得到的:

The solution to this is to add a small chunk of random data -- called a salt -- to the password before it's hashed:

如果bcrypt自动处理所有内容,他们为什么要解释所有这些?

hash(salt + p) #=> 
The salt is then stored along with the hash in the database, and used to check potentially valid passwords:

 =? hash(salt + just_entered_password)
bcrypt-ruby automatically handles the storage and generation of these salts for you.

有人可以解释一下bcrypt如何存储和生成这些盐吗?为什么它说它为我处理这一切然后继续告诉我如何生成盐?我需要在我的模型中运行这样的东西:self.password_hash = hash(salt + p)

我很困惑,我曾经完全得到盐和哈希,现在他们已经改变了一切.可怕的,不清楚的文档 ...它们似乎向您展示了如何在没有盐的情况下使用bcrypt和大量示例,然后简要地提到如何在底部使用盐正确地执行此操作.

有人可以举个例子来说明如何使用新版本的bcrypt来生成salt和hash,以及如何进行身份验证?

1 个回答
  • 好的,has_secure_password真的很酷.您不再需要担心盐和哈希值,盐和哈希值将作为一个属性(password_digest)存储在数据库中.

    它以这样的方式保存,即bcrypt知道password_digest字符串的哪个部分是salt,什么是hash.

    如果您从头开始设置身份验证,则需要执行以下操作:

    1)添加bcrypt rails gem:

    gem bcrypt-rails
    

    2)将has_secure_password方法添加到负责处理用户记录的模型中:

    class User < ActiveRecord::Base
        has_secure_password
    end
    

    3)确保您的users表有一password_digest列:

    class CreateUser < ActiveRecord::Migration
        create_table :users do |t|
            t.username
            t.password_digest
        end
    end
    

    4)创建一个new方法来为要使用的表单创建一个新的空用户实例:

    class UsersController < ApplicationController
        def new
            @user = User.new
        end
    end
    

    5)在new视图中,创建一个创建填充params hash' :password:username条目的表单:

    <% form_for( @user ) do |f| %>
        <%= f.text_field :username %>
        <%= f.password_field :password %>
    <% end %>
    

    6)返回我们的控制器,使用强参数允许用户名和密码.强大的params背后的全部原因是为了防止一些厚颜无耻的chappy使用开发工具创建自己的html表单字段(例如与id相关的字段)并用恶意数据填充数据库:

    class UsersController < ApplicationController
        def new
            @user = User.new
        end
    
        private
    
        def user_params
               params.require(:user).permit(:username, :password)
        end
    end
    

    7)让我们创建一个create方法,它将使用这些允许的条目来创建一个新用户,由表单填充:

    class UsersController < ApplicationController
        def new
            @user = User.new
        end
    
        def create
                @user = User.new(user_params)
                @user.save
                redirect_to root_path
        end
    
        private
    
        def user_params
               params.require(:user).permit(:username, :password)
        end
    end
    

    根据您的需要设置您的路线,就是这样!用户记录的password_digest列将自动填充一个字符串,该字符串由附加密码哈希值的salt组成.十分优雅.

    所有你需要记住:password- > password_digest.

    为了授权用户并注销用户,使用create方法和destroy方法创建会话控制器:

    def create
      user = User.find_by_email(params[:email])
      if user && user.authenticate(params[:password])
        session[:user_id] = user.id
        redirect_to admin_root_path, :notice => "Welcome back, #{user.username}"
      else
        flash.now.alert = "Invalid email or password"
        redirect_to root_path
      end
    end
    
    def destroy
      reset_session
      flash[:info] = "Signed out successfully!"
      redirect_to root_path
    end
    

    希望这有助于某人!

    2023-02-03 12:31 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有