«前の日記(2014-03-05) 最新 次の日記(2014-03-09)» 編集

いがいが日記


2014-03-06 [長年日記]

_ omniauth-identity

OmniAuth、twitter認証やfacebook認証が簡単に作れて便利ですね。omniauth-identity gem を使うと自前のパスワード認証も簡単につくれます。AsciiCast に解説もあっていたれりつくせり。

メールとパスワードの入力Webページは omniauth-identity が自動でつくってくれて便利ですが、APIからユーザーを作りたい場合にコントローラでどうすればいいのか調べたのでメモ。難しいことは何もなく、Identityモデルでpassword に代入する際にpassword_digestを計算して入れてるだけだった。

なので、

i = Identity.new(name: "igaiga", email:"igaiga@example.com", password: "igaigapass")

これでpassword_digest が代入されてる。あとは i.save! すればOK。

実際にやってるのは omniauth-identity gemの以下。

OmniAuth::Identity::SecurePassword::InstanceMethodsOnActivation#password=
def password=(unencrypted_password)
  @password = unencrypted_password
  if unencrypted_password && !unencrypted_password.empty?
    self.password_digest = BCrypt::Password.create(unencrypted_password)
  end
end

ところで、saltはないんですね。最近の認証システムにはsaltないなー、と思って調べてみた。

ここに詳しく書いてある。簡単に言うとこんな感じ。

  • BCrypt::Password.create(unencrypted_password) をつかっている。
  • これはsaltを保存しなくてよい仕組み。(中で自動生成)
  • そもそもsalt は何のためにあるかと言うと、攻撃者が総当たりで攻撃したときに時間がかかるようにするため。
    • 暗号化された文字列が流出したときの話
    • paswordとsaltを1つずつずらして暗号化して・・・を繰り返させる
  • そこで、攻撃者が計算するときに(saltがあったときよりも)十分に遅ければ、別途saltを保存しなくても良いはず
  • 普通のhash(MD5とか)は遅くは設計されてない。速く計算されてしまう。
  • bcrypt は暗号化計算が十分に遅い。秒間450個のパスワードしか生成できない。(MD5だと約140,000個)

なるほど。どれどれ。

require 'bcrypt'
start = Time.new
100.times { |i| BCrypt::Password.create(i) }
finish = Time.now
p "#{finish - start} sec"

実行させたら100個暗号化するのに 6.247545 sec だった。確かにかなり遅くできてる。

3/7 追記: Omniauth-identity、ascii cast に従ってname, emai, password_digestを作ったけど、表示しなければname要らないか。


«前の日記(2014-03-05) 最新 次の日記(2014-03-09)» 編集