12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHP で生成したパスワードハッシュが Python でマッチするか確認

Posted at

環境

PHP 7.1
Python 2.7.6

確認したいこと

現在、PHP で新規開発をしていて、パスワードの暗号化に password_hash を使用している。
かなり先のことだが、将来的に別の言語(ここでは Python)に移行した際に、暗号化したパスワードが同じように使えるのか疑問:question:
つまり、 Python に移行してもユーザーのパスワードの照合が正常にできて、ログインできることを確認したい。
もう少しミクロな言い方をすると、 password_hash は Blowfish という暗号化アルゴリズムを使用しているので(後述)、Python でも Blowfish が使えて照合できるかを確認したい。

PHP で暗号化する

.php
password_hash('password', PASSWORD_DEFAULT);
// $2y$10$BN2hH0B3gnZceNlW1JXiNOUN8NWybLlfqZh6WQ/imah4htM8fktFW

password_hash('password', PASSWORD_BCRYPT);
// $2y$10$CuZkO0N29B1YtHHI9mwvIOCSUitQh4ptyfxYWvHhHoHHP2GZqC5Ga

解説

password_hash では現在、PASSWORD_DEFAULT と PASSWORD_BCRYPT という 2 種類の定数を指定できる。
http://php.net/manual/ja/function.password-hash.php

定数の中身を確認してみた(スタブだけど)

/php/lib/php.jar!/stubs/standard/password.php
define("PASSWORD_DEFAULT", 1);
define("PASSWORD_BCRYPT", 1);

結局 PASSWORD_DEFAULT も PASSWORD_BCRYPT も同じ値を指している。
この場合、Bcrypt での実装になる。
Bcrypt ≒ Blowfish なので、現在の password_hash の暗号化アルゴリズムは必ず Blowfish になるもよう。

※ Bcrypt の解説はここが分かりやすかった
https://goo.gl/kpS5En

※他の暗号化アルゴリズムを使いたかったら Crypt を使えばできそう
http://php.net/manual/ja/function.crypt.php

Python で照合できるか確認

.py
import bcrypt

password = b'password'
phpHash = '$2y$10$BN2hH0B3gnZceNlW1JXiNOUN8NWybLlfqZh6WQ/imah4htM8fktFW'

if bcrypt.checkpw(password, phpHash):
    print("It Matches!")
else:
    print("It Does not Match :(")

# It Matches!

無事にマッチした :ok_woman_tone1:

解説

  • bcrypt モジュールを用いて、PHP で暗号化したパスワードがマッチするか確認している
  • 事前に bcrypt というモジュールのインストールが必要
  • bcrypt.checkpw が PHP で言う password_verify にあたる

マメ知識(知らなかっただけ)

PHP の password_hash を用いて生成した値の暗号化バージョン(1番左の部分)は $2y$ になる。
しかし Python の bcrypt モジュールを用いて生成する場合、暗号化バージョンは $2a$$2b$ のみしか指定できないもよう。

.py
salt = bcrypt.gensalt(rounds=10, prefix=b'2a')
password = b'password'
hashed = bcrypt.hashpw(password, salt)

prefix の部分

これでは同じパスワードとみなしてくれないのでは?:rolling_eyes: と思ったが、上述の通りマッチした。
逆に bcrypt.hashpw で生成した値を password_verify で照合しても無事にマッチした。
つまり、暗号化バージョンが $2a$$2y$ のように異なっていても同じパスワードとして認識してくれるので、将来的に Python に移行した際にわざわざ $2y$$2a$ に置換するなどの処理は不要。

12
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?