Open2

Sorceryとdeviseの認証ロジック比較

とぴとぴ

パスワード生成ロジック

どちらもbcrypt-rubyをつかっている

https://github.com/bcrypt-ruby/bcrypt-ruby

デフォルト設定

cost

ハッシュ化を繰り返す回数。回数が多ければ時間がかかる。
デフォルトは12回、最小設定可能は4回で最大は31回

secret_bytesize

secretsで使える最大バイト数。デフォルトは72。
古いバージョンは72を超えると切り捨てられ、最新バージョンでは切り捨てられないが前方互換性のために切り捨てられる。設定で変えられる?不明。これによりUbuntu18.04⇨Ubuntu20.04にアップグレードしてもパスワードが無効になることはないらしい。
255を超えるとnilを返すので8ビット管理っぽそう

salt

塩。ユーザー別に付与するランダムに生成される値。この値を付与してパスワードをハッシュ化する。
ユーザー別なのでDBに保存する。
レインボーテーブル攻撃(事前計算攻撃)を防げる
⇨付与されるものがわかるtpパスワード生成ロジック

どちらもbcrypt-rubyをつかっている

https://github.com/bcrypt-ruby/bcrypt-ruby

デフォルト設定

cost

ハッシュ化を繰り返す回数。回数が多ければ時間がかかる。
デフォルトは12回、最小設定可能は4回で最大は31回

secret_bytesize

secretsで使える最大バイト数。デフォルトは72。
古いバージョンは72を超えると切り捨てられ、最新バージョンでは切り捨てられないが前方互換性のために切り捨てられる。設定で変えられる?不明。これによりUbuntu18.04⇨Ubuntu20.04にアップグレードしてもパスワードが無効になることはないらしい。
255を超えるとnilを返すので8ビット管理っぽそう

salt

塩。ユーザー別に付与するランダムに生成される値。この値を付与してパスワードをハッシュ化する。
ユーザー別なのでDBに保存する。
レインボーテーブル攻撃(事前計算攻撃)を防げる
⇨付与されるものがわかっちゃうとパスワード特定難易度が下がる感じかな。

生成方法

RubyのプラットフォームがJava、そうでなければC言語で生成。
C言語の場合はOpenSSLでランダム生成。デフォルトだと最大16バイトの長さで生成される。

pepper

胡椒。全ユーザー共通の秘密鍵。こちらもパスワードに付与してハッシュ化する。
ハッシュ化したパスワードが漏洩しても、pepperが分からなければハッシュ値から元のパスワードを推測しにくくなる。
そういうわけで環境変数みたいな別扱いになる。秘匿情報のひとつ。
ここに書いちゃったけどbcrypt-rubyでは使っていないみたい。

とぴとぴ

devise

パスワード生成

cost

デフォルトは12、テストだと1。設定で変更可能。
devise内ではstretchesという名前で扱ってる。
https://github.com/heartcombo/devise/blob/cf93de390a29654620fdf7ac07b4794eb95171d0/lib/generators/templates/devise.rb#L126

  # Limiting the stretches to just one in testing will increase the performance of
  # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
  # a value less than 10 in other environments. Note that, for bcrypt (the default
  # algorithm), the cost increases exponentially with the number of stretches (e.g.
  # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
  config.stretches = Rails.env.test? ? 1 : 12

パスワードの長さ制限

6~128の間。設定で変更可能。

salt

使用していない。生成されるスキーマにもないので使う場合は拡張しないといけない。

pepper

デフォルトはなさそう。
設定ファイルだとコメントアウトされている。

  # Set up a pepper to generate the hashed password.
  # config.pepper = '<%= SecureRandom.hex(64) %>'

クラス変数の初期値もnil

  # Used to hash the password. Please generate one with rails secret.
  mattr_accessor :pepper
  @@pepper = nil

ハッシュ化

パスワード+pepperでハッシュ化
pepperは初期値nilなので、設定している場合は付与されるのでより堅牢になりそう。
https://github.com/heartcombo/devise/blob/cf93de390a29654620fdf7ac07b4794eb95171d0/lib/devise/encryptor.rb#L9

module Devise
  module Encryptor
    def self.digest(klass, password)
      if klass.pepper.present?
        password = "#{password}#{klass.pepper}"
      end
      ::BCrypt::Password.create(password, cost: klass.stretches).to_s
    end

ハッシュ化の方法

bcryptを使う場合は使わない。
もし違うハッシュ化の方法変えたい場合はdevise-encryptableというGemが別途必要。
そしたらbcryptは使わない。

  # Require the `devise-encryptable` gem when using anything other than bcrypt
  # config.encryptor = :sha512

流れ

パスワードを6-128の間で入力

pepperが設定されていたらパスワードの後ろにつける。

bcryptでハッシュ化

encrypted_passwordに保存される