はじめに
- パスワードのハッシュ化とパスワードの認証をする方法について本やネットの情報から調べて理解したことをまとめました。
- もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。
- ここでは、password_hash関数とpassword_verify関数を使ってパスワードのハッシュ化とパスワードの認証をする方法について解説します。
ハッシュ化とは
ハッシュ関数とは
- ハッシュ関数(md5、sha1、sha256、password_hash関数 など)を使うと、特定の決まりに基づいて文字列を置換します。
- ハッシュ化は不可逆変換しているため、一度ハッシュ化すると元に戻すことはできません。
ハッシュ化をする2つの理由
ハッシュ化をする理由は2つあります。
理由1:セキュリティのため
- パスワードを保存したデータベースに悪意のある人から攻撃された場合、パスワード情報が盗まれて悪用されてしまいます。そのため、セキュリティの面でハッシュ化する必要があります。
理由2:パスワードをサイトの管理者に知られないようにするため
- サイトの管理者によってもデータベースに保存された情報を悪用されてしまうケースがあります。
- パスワード情報の流出や不正利用を防止するためにハッシュ化する必要があります。
パスワードをハッシュ化する方法
ここからは、パスワードをハッシュ化する方法について紹介します。
パスワードをハッシュ化するためにpassword_hash関数を使います。
password_hash関数の書き方
password_hash($password , $algo , $options)
引数
-
$password
:ハッシュ化したいパスワードの文字列 -
$algo
:アルゴリズムの指定 -
$options
:オプションの指定
パスワードの認証をする方法
パスワードを認証する方法について紹介します。
パスワードを認証するためにpassword_verify関数を使います。
password_verify関数の書き方
password_verify ( $password , $hash )
引数
-
$password
:認証したいパスワード -
$hash
:ハッシュ化されたパスワード
パスワードのハッシュ化とパスワード認証のコード例
以下のようなデータベースとテーブルがあると仮定して解説します。
データベース名: test_db5
テーブル名: users
password | |
---|---|
- | - |
Webサイトで使われている会員登録機能
とログイン機能
を実装することを仮定して解説します。
会員登録機能のコード例(password_hash関数)
signup.php
<?php
$user = "ここにユーザー名が入ります";
$password = "ここにパスワードが入ります";
try{
$dbh = new PDO("mysql:host=localhost; dbname=test_db5; charset=utf8", "$user", "$password");
$stmt = $dbh->prepare("INSERT INTO users (email, password) VALUES (:email, :password)");
$stmt->execute(array(':email' => $_POST['email'],':password' => password_hash($_POST['pass'], PASSWORD_DEFAULT)));
}catch(Exception $e){
echo "データベースの接続に失敗しました:";
echo $e->getMessage();
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>会員登録</title>
</head>
<body>
<h1>会員登録</h1>
<form action="" method="post">
<p>
<label>メールアドレス:</label>
<input type="text" name="email">
</p>
<p>
<label>パスワード:</label>
<input type="password" name="pass">
</p>
<input type="submit" name="submit" value="会員登録する">
</form>
</body>
</html>
signup.phpの画面
以下の内容を入力して、会員登録する
ボタンを選択します。
データベースの中身
ログイン機能のコード例(password_verify関数)
login.php
<?php
$user = "ここにユーザー名が入ります";
$password = "ここにパスワードが入ります";
try{
$dbh = new PDO("mysql:host=localhost; dbname=test_db5; charset=utf8", "$user", "$password");
$stmt = $dbh->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(array(':email' => $_POST['email']));
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if(password_verify($_POST['pass'], $result['password'])){
echo "ログイン認証に成功しました";
}else{
echo "ログイン認証に失敗しました";
}
}catch(Exception $e){
echo "データベースの接続に失敗しました:";
echo $e->getMessage();
die();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
<form action="" method="post">
<p>
<label>メールアドレス:</label>
<input type="text" name="email">
</p>
<p>
<label>パスワード:</label>
<input type="password" name="pass">
</p>
<input type="submit" name="submit" value="ログインする">
</form>
</body>
</html>
パスワード認証に成功するとログイン認証に成功しました
と表示され、失敗するとログイン認証に失敗しました
と表示されるようにします。
login.phpの画面
データベースに保存されている情報を入力して、ログインする
ボタンを選択します。