概要
Ruby のコード上またはコンフィグファイルなどでパスワードを管理する場合があると思います 平文だとさすがにあぶないので何かしらの方法で暗号化して記載する必要があるかなと思います
今回は bcrypt を使って暗号化して保存する方法を紹介します
環境
- macOS 11.6
- Ruby 3.0.2p107
- bcrypt 3.1.16
準備
- bundle init
- vim Gemfile
gem "bcrypt"
- bundle install
暗号化されていないコード
まずは暗号化されていないコードを紹介します パスワードが平文で保存されているのがわかるかなと思います
require 'io/console'
password = "hoge"
input_password = STDIN.noecho(&:gets).chomp
puts input_password == password
これを実行する場合には以下のようにします
- bundle exec ruby test.rb
これでターミナル上でパスワードの入力を求められるので適当に文字列を入力しましょう
当然「hoge」と入力した場合は true が出力されます
見ての通り認証するためのパスワード情報を平分で管理しているので危険です
パスワードを暗号化して管理する
bcrypt を使います
require 'io/console'
require 'bcrypt'
password = BCrypt::Password.new("$2a$12$8HvnCbkJHhqJMtXdmgAwJeNOlOpSubId3yvk64RC/JqXW8uNZ3Vti") # => hoge
input_password = STDIN.noecho(&:gets).chomp
puts password == input_password
同じように実行してみましょう
- bundle exec ruby test.rb
これで同じように「hoge」を入力すると true が出力されるのが確認できます
暗号化されたパスワードを生成する方法は
BCrypt::Password.create("hoge")
でできます
ポイント
BCrypt::Password.new で生成したオブジェクトの == メソッドを使うのがポイントです
もし上記のコードで比較の部分を以下のように書き換えると例えパスワードが合っていても false が返ります
puts password == input_password
これは String クラスの == を使っているのでエラーになっています
input_password を puts してみるとわかりますが暗号化されたままのパスワードが表示されます なので単純に文字列クラスの比較を使ってもエラーになるので BCrypt::Password クラスのオブジェクトを元に比較するのが重要です
最後に
今回は Ruby 上だけで解決する方法を紹介しました
データベースなどを使えばデータベース側の暗号化機能も使えるので Ruby 側で考える必要はなくなります
基本的に復号化できないのでハッシュ化されたパスワードが漏洩しても元のパスワードを取得するのができないのが bcrypt のメリットです
ただ逆に言うと復号化して使うことはできないのでコード上のパスワードを情報を使って外部に認証する場合などはこの方法は使えません
あくまでもこの方法はユーザからの入力に対して暗号化する手法になります
とにかく重要なのはコードやデータベース上に平文のパスワードなどは保存しないようにすることが重要です そもそも漏洩しないことが重要ですが
0 件のコメント:
コメントを投稿