我想通过使用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:我知道密码以明文形式存储我稍后会修复:)
答案 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