Help us understand the problem. What is going on with this article?

【PHP】パスワードのハッシュ化とパスワードの認証をする方法

More than 1 year has passed since last update.

はじめに

  • パスワードのハッシュ化とパスワードの認証をする方法について本やネットの情報から調べて理解したことをまとめました。
  • もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。
  • ここでは、password_hash関数とpassword_verify関数を使ってパスワードのハッシュ化とパスワードの認証をする方法について解説します。

ハッシュ化とは

  • 「ハッシュ化」とは、ハッシュ関数によって文字列を置換して、元の文字を推測できなくすることです。
  • 以下のpasswordの部分がハッシュ化された値です。 スクリーンショット 2019-06-02 16.03.10.png

ハッシュ関数とは

  • ハッシュ関数(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

email 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の画面

以下の内容を入力して、会員登録するボタンを選択します。

スクリーンショット 2019-06-02 16.00.53.png

データベースの中身

パスワードがハッシュ化して保存されました。
スクリーンショット 2019-06-02 16.03.10.png

ログイン機能のコード例(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の画面

データベースに保存されている情報を入力して、ログインするボタンを選択します。
スクリーンショット 2019-06-02 16.04.02.png

実行結果

パスワード認証に成功したのでログイン認証に成功しましたと表示されます。
スクリーンショット 2019-06-02 16.04.11.png

wakahara3
27歳未経験からwebエンジニアに転職しました。エンジニアとしてスキルアップしていくために取り組んだことをQiitaに公開していきます。もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away