2013-02-17 35 views
2

我想通過使用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 

它保險箱就好了,但是當我打電話,以查找我得到一個異常的用戶檢索看起來密碼哈希包含非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:我知道密碼被保存在明確的類型後,我將修復:)

回答

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