2

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:パスワードがクリアタイプで保存されることはわかっています。後で修正します:)

4

1 に答える 1

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
于 2013-02-18T14:17:56.330 に答える