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

パスワード生成ロジック
どちらもbcrypt-rubyをつかっている
デフォルト設定
cost
ハッシュ化を繰り返す回数。回数が多ければ時間がかかる。
デフォルトは12回、最小設定可能は4回で最大は31回
secret_bytesize
secretsで使える最大バイト数。デフォルトは72。
古いバージョンは72を超えると切り捨てられ、最新バージョンでは切り捨てられないが前方互換性のために切り捨てられる。設定で変えられる?不明。これによりUbuntu18.04⇨Ubuntu20.04にアップグレードしてもパスワードが無効になることはないらしい。
255を超えるとnilを返すので8ビット管理っぽそう
salt
塩。ユーザー別に付与するランダムに生成される値。この値を付与してパスワードをハッシュ化する。
ユーザー別なのでDBに保存する。
レインボーテーブル攻撃(事前計算攻撃)を防げる
⇨付与されるものがわかるtpパスワード生成ロジック
どちらも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
という名前で扱ってる。
# 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なので、設定している場合は付与されるのでより堅牢になりそう。
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
に保存される