LoginSignup
1
1

More than 3 years have passed since last update.

PHP ハッシュ関数

Last updated at Posted at 2021-04-15

はじめに

・PHPで、セキュリティに関心がある方
・ハッシュ、ハッシュ関数が分からない方

ハッシュとは

ハッシュとはアルゴリズムに基づき、読解不可能な文字列などに置換する仕組みのことです。

※パスワードなどの機密情報を扱う時になどに使用します。

代表的なハッシュ関数

PHPには標準で、文字列からハッシュ値を計算し、生成する関数が存在します。

※以下が代表的な、ハッシュ関数です。

ハッシュ関数 詳細
hash 指定したアルゴリズムで、ハッシュ値を生成する ※バージョン 5.1.2以降
md5 MD5方式で、16進数・32文字のハッシュ値を生成する
sha1 SHA-1方式で、16進数・40文字のハッシュ値を生成する
password_hash 機密性の高い文字列のハッシュ値を生成する ※バージョン 5.5以降

hash

sample_hash.php
<?php 
$str = 'hoge';
var_dump(hash("sha256", $str));
 ?>
実行結果
string(64) "ecb666d778725ec97307044d642bf4d160aabb76f56c0069c71ea25b1e926825"       

md5

sample_md5.php
<?php
$str = 'hoge';
var_dump(md5($str));
 ?>
実行結果
string(32) "a577f0035386e7d04551e867b3d9f024"               

sha1

sample_sha1.php
<?php
$str = 'hoge';
var_dump(sha1($str));
 ?>
実行結果
string(40) "31f30ddbcb1bf8446576f0e64aa4c88a9f055e3c"          

password_hash

sample_password_hash.php
<?php 
// ハッシュ値を計算する前の文字列
$str = "hoge";

// ハッシュ値を計算
password_hash($str, PASSWORD_DEFAULT);
 ?>
実行結果
string(60) "$2y$10$zgsW6rm.9wcBnkSw2/Jp3OiJSDy5gsEUAM6fum4zva7/5jauNVixK"        

おまけプログラム

IDとパスワードを入力し、DBに保存するプログラムを作成しました。なお、パスワードはpassword_hashを使用し、ハッシュ化しています。

※今回使用するDB情報

ユーザー名 DB名 カラム名情報① カラム名情報②
id_pass_user hashdb id_data varchar(100) pass_data varchar(100)

新規で作成した、ユーザーにはパーミッション(権限)がないので、以下のコマンドで付与します。今回の場合は、id_pass_userにDBレベル(hashdb)での付与になります。

パーミッションの付与(DBレベル)
mysql> grant all on hashdb.*to id_pass_user@localhost;

※入力する、IDとパスワード

ID パスワード
hogeID hogePASS

コード一覧

data_vaildataion.php
<?php
// ID,パスワードと、DBのバリデーションの補助を実装したクラス
class DataVaildataion {

    //ID,パスワードと、DBのバリデーションに必要なデータをカプセル化
    private $hash_pass = null;
    private $success_message = null;
    private $error_message = null;
    private $clean = array();


    # ゲッターは今回必要ないので、コメントアウト

    /*public function getHashPass() {
        return $this->hash_pass;
    }

    public function getSuccessMessage() {
        return $this->success_message;
    }

    public function getErrorMessage() {
        return $this->error_message;
    }

    public function getClean() {
        return $this->clean;
    }*/

    // セッターで、ID,パスワードのバリデーションの補助    
    public function setHashPass($hash_pass) {
        return $this->hash_pass = $hash_pass;
    }

    public function setSuccessMessage($success_message) {
        return $this->success_message = $success_message;
    }

    public function setErrorMessage($error_message) {
        return $this->error_message = $error_message;
    }

    public function setClean($clean) {
        return $this->clean = $clean;

    }
}
 ?>
db.php
<?php
// 必要なプロパティのあるクラスファイルの呼び出しと、インスタスの生成
require_once('data_vaildataion.php');
require_once('from.php');
$data = new DataVaildataion(); 

// データベースの接続情報を定数で実装
define( 'DB_HOST', '127.0.0.1'); # phpadminの場合は、localhost
define( 'DB_USER', 'id_data_user');
define( 'DB_PASS', '各自のパスワード');
define( 'DB_NAME', 'hashdb');


// Dataクラスのセッターを使用し、ID,パスワードのバリデーションを実装
if(!empty($_POST['btn_submit'])) {

    if(empty($_POST['id_data']) || empty($_POST['pass_data'])) {
        echo $data->setErrorMessage('IDまたは、パスワードが未入力です。').PHP_EOL;
        exit();
    }else {

        // Dataクラスのセッターを使用し、IDのサニタイズの実装 (シングルクフォートと、ダブルクフォートをHTMLに変換しない)
        $data->setClean($clean['id_data'] = htmlspecialchars( $_POST['id_data'], ENT_QUOTES));

        // 上記と同じく、パスワードのサニタイズの実装
        $data->setClean($clean['pass_data'] = htmlspecialchars($_POST['pass_data'], ENT_QUOTES));

        // セキリュティを考慮し、password_hashを採用(同じハッシュを生成しない。DBとの比較の際は、password_verifyを採用)
        $data->setHashPass($hash_pass['hash_pass'] = password_hash($clean['pass_data'], PASSWORD_DEFAULT));
    }

    // Dataクラスのセッターを使用し、DBのバリデーションを実装後、DBに保存
    if(empty($data->setErrorMessage($error_message)) ) {

        $mysqli = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME);
        if($mysqli->connect_errno ) {
            echo $data->setErrorMessage('エラー番号 '.$mysqli->connect_errno).PHP_EOL;
            exit();
        }else{
            $sql = "INSERT INTO hash (id_data, pass_data) VALUES ( '$data->setClean($clean[id_data])', '$data->setClean($hash_pass[hash_pass])')";
        }

        $res = $mysqli->query($sql);
        if($res) {
            echo $data->setSuccessMessage('登録が完了しました。');
        }else{
            echo $data->setErrorMessage('登録に失敗しました。');
        }
        $mysqli->close();
    }
}
?>
from.php
<?php
require_once('data_vaildataion.php');
?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ハッシュ化しよう</title>
</head>
<body>
    <h1>新規登録画面</h1>
    <div class="input_area">
        <form action="db.php" method="post">
            <dl class="id">
                <dt>ID</dt>
                <dd><input type="text" name="id_data"></dd>
            </dl>
            <dl class="pass">
                <dt>PASS</dt>
                <dd><input type="text" name="pass_data"></dd>
            </dl>
             <input type="submit" name="btn_submit" value="新規登録">
        </form>
    </div>
</body>
</html>
hashdb
+----+---------+----------------------------------------------------------------+
| id | id_data | pass_data                                                      |
+----+---------+----------------------------------------------------------------+
|  1 | (hogeID)  | ($2y$10$0V2iu9qPDLJ/LOo629jT2OSNWlEHqUzADek23k.Ns.swWZiT3GRxu) |
+----+---------+----------------------------------------------------------------+

※上記のコードで、IDとハッシュ化されたパスワードがDBに保存できます。

参考サイト
文字列からハッシュ値を取得する

1
1
0

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
1
1