检索密码哈希时出现编码错误

时间:2013-02-17 22:36:12

标签: ruby-on-rails couchbase

我想通过使用PBKDF2并在数据库中存储密码哈希和salt来实现用户身份验证。

我的用户类看起来像这样

class User < Couchbase::Model
  require 'pbkdf2'

  attribute :name
  attribute :surname
  attribute :email
  attribute :type
  attribute :password
  attribute :password_hash
  attribute :password_salt

  attribute :user_since, :default => lambda{ Time.now }

  #... Some not so interesting validates

  before_create :prepare_to_create

  #returns the document of the user found for the given id
  def self.retrieve(id)
    return User.bucket.get(id)
  end

  def encrypt_password
    if self.password.present? then
      hashedpassword = create_password(self.password)
    self.password_hash = hashedpassword.value
    self.password_salt = hashedpassword.salt
    end
  end

  #Creates a new PBKDF2 instance with the given string
  #and the given salt. If no salt is specified
  # a SecureRandom.base(16) string is used
  def create_password(pwString, saltString = SecureRandom.urlsafe_base64(16))
    password = PBKDF2.new do |p|
      p.password = pwString
      p.salt = saltString
      p.iterations = 5000
    end
  end

  def prepare_to_create
    encrypt_password
    @id = User.bucket.incr("user_key", 1, :initial => 1).to_s
  end

end

控制器看起来像这样:

class UsersController < ApplicationController
  def new
    @user = User.new
    @user.type = params[:type]
  end

  def create
    @user = User.new(params[:user])    
    if @user.save
      data = User.retrieve(@user.id)
      newUser = User.new(:name => data[:name],
                         :surname => data[:surname],
                         :email => data[:email],
                         :type => data[:type],
                         :password => data[:password])

      redirect_to root_url, :notice => "You successfully signed up " + newUser.full_name 
    else
      render "new"
    end
  end

end

它保证很好但是当我调用retrieve以查找用户时,我得到一个异常,看起来密码哈希包含非UTF-8字符。

看起来像这样:

Couchbase::Error::ValueFormat (unable to convert value for key '8': lexical error: invalid bytes in UTF8 string.
      :"123456","password_hash":"\r�����;��X�\u001E���S=c\u0018���
                 (right here) ------^
):

现在我想知道我是否必须以某种方式清理密码。我是否必须逃避一些角色?或者我应该使用其他加密功能吗?

PS:我知道密码以明文形式存储我稍后会修复:)

1 个答案:

答案 0 :(得分:2)

好吧,如果你只是调用hashedpassword.value,你得到哈希的二进制表示,你必须调用它如下:

def encrypt_password
    if self.password.present? then
      hashedpassword = create_password(self.password)
      self.password_hash = hashedpassword.hex_string
      self.password_salt = hashedpassword.salt
  end
end