PHPのpassword_hashとpassword_verifyをNodejsで互換性を持たせるための話

2022年1月8日

テクノロジー

eyecatch 異常にご完成を重要視する、ユゲタです。 互換性があれば、データの相互やり取りや、環境における適正システムの幅が広がります。 要するに、「どっちを使ってもいいよ」的な範囲を広げることができますからね。 ということで、PHPで使っていたデータをNodejsの自作フレームワークで使ってみよう計画を進めているユゲタですが、 今回は、PHPで作ったwebサービスのログインシステムを、今作っているNodejsのMyフレームワークに載せ替えて、同じデータベースを使ってしまおう活動の真っ盛りで、 その方式がうまくできたので、備忘録がわりに、苦労話も踏まえて、ブログに残しておきたいと思います。

イケてるパスワード管理

PHPには、ユーザーが登録する時のパスワードを平文でデータベースに登録するというアホな事はせずに、"password_hash"という便利な機能があります。 これは、ユーザーのパスワードhash化して、いわゆる復元不可のパスワードにしてしまいます。 それをデータベースに登録すれば、漏洩してもパスワードは漏洩されずに済むので、安全安心の仕様ですね。 よく、ユーザーサポートに連絡して、「登録してあるパスワードを教えて欲しい」という問い合わせをする人がいますが、 基本的に今どきのアカウント登録は、パスワード自体は登録されておらず、hash化されたデータとして登録されています。 そして、ログインの時には、そのパスワードが合っているかどうかを登録されているhash値と比較して、マッチしているかどうかを判定できる、"password_verify"という機能があり、 この2つのパスワード機能のおかげで、安全なシステム構築ができるようになっています。 もし、今どきパスワードを平文で登録しているシステムを運用している人がいたら、それはもうすぐにでも変更しないととんでもない結果に繋がる可能性がありますよ。 ちなみに、簡単なサンプルプログラムを書いておくので、気になる人はチェックしてみてください。 // password_hash $pass_text = "hoge"; $hash = password_hash($pass_text, PASSWORD_DEFAULT); > $2y$10$Yga9wzhnZ7wLUA/.FkVnxeLBf6IPzROGUOYwOJDaiqF06d1m98Mu2 // password_verify password_verify($pass_text , $hash); > true password_verify("hage", $hash); > false 【参考】 https://www.php.net/manual/ja/function.password-hash.php https://www.php.net/manual/ja/function.password-verify.php

Nodejsでのパスワード認証管理

そして、次に上記で作られたパスワードのhash値を、Nodejsでそのまま利用したい。 さらに、Nodejsでもpassword_hashを作りたいという事で色々調べてみたら、便利なライブラリが存在しました。 https://www.npmjs.com/package/bcryptjs このツールで、全く同じ処理を行うことができたので導入手順と、サンプルプログラムを書いておきます。 まず、npmでライブラリを、インストールしておきます。 $ npm install bcryptjs --save 次にコードは以下の通りです。 const bcrypt = require("bcryptjs"); const len = 11; const pass_text = "hoge"; // パスワードをhash化 const salt = bcrypt.genSaltSync(len); const hash = bcrypt.hashSync(pass_text, salt); > $2y$10$AyAfOKT6SYLZwRsD.9w43ekY6bqSyXFpLV1IocWKUFnA7ZWlQ.JTO // ログインの時に入力されたパスワードをhash化されたパスワードと比較 const bool = bcrypt.compareSync(pass_text, hash); > true const bool = bcrypt.compareSync("hage", hash); > false 参考: https://www.npmjs.com/package/bcryptjs

ハマりどころ

このライブラリと似た「bcrypt」というのがありますが、そっちは、bcryptアルゴリズムというhash変換方式になっているので、認証がうまく通らなくなってしまいます。 PHPでのpassword_hashにかかれている"PASSWORD_DEFAULT"というアルゴリズム指定が、こちらを使うように推奨されているのですが、"CRYPT_BLOWFISH"という方式を使った場合は、 後者のbcrypyライブラリを使うと認証できるようになります。 "PASSWORD_DEFAULT"の時は、bcryptjsを使うようにしましょう。 ググっていると、bcryptの解説ばかりしていたので、ハマってこのブログにたどり着いた方、おまたせしました、ご利用くださいませ。 そんな、ここでハマって、数時間費やした、ユゲタでした。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ