2
1

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 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に保存できます。

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

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?