PBKDF2を使用し、パスワードハッシュとソルトをデータベースに保存してユーザー認証を実装したい。
私のユーザークラスは次のようになります
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:パスワードがクリアタイプで保存されることはわかっています。後で修正します:)