【PHP】HMACとソルトを使ってハッシュを生成してみる

article-thumbnail

こんにちは、いつもお読みいただきありがとうございます。
Ken(@gootablog)です。

APIを使う時にパスワードが必要な時があり、データベース内のデータを使ってPHPでハッシュ値を生成しました。その時のやり方を書いていきたいと思います。

ハッシュ値を生成するコード

ソルト(Salt)を用いてストレッチングをして生成するやるかたを使用しました。
その他にもHMACという方法もあることを知ったのでそちらの方法も書いてみました。

以下PHPではハッシュ値を生成するコードです。

$obj = new Hash_Salt();
$hash = $obj -> generate('message');
echo "Stretching : ".$hash;

echo nl2br("\n");

$obj = new Hash_Hmac();
$hash = $obj -> generate('message');
echo "Hmac : ".$hash;


//Salt
Class Hash_Salt
{
    protected $stretch_count = 1000;
    protected $salt = 'j25xggyijp2hmbp98fij6xkmpjtcpi';

    public function generate($message) {

        $hash = '';
        for($i=1; $i<=$this -> stretch_count; $i++) {
            $hash = hash('sha256', $message.$this -> salt.$hash);
        }

        return $hash;
    }
}


//HMAC
Class Hash_Hmac
{
    protected $secret_key = 'pt49fw8fcnwu4tej6i7776utyparpw';

    public function generate($message) {
        $hash = hash_hmac('sha256', $message, $this -> secret_key);
        return $hash;
    }
}


ソルトとストレッチング

ソルトとストレッチングを使ったやり方を見ていきます。

protected $stretch_count = 1000;
protected $salt = 'j25xggyijp2hmbp98fij6xkmpjtcpi';

まずは定数を設定します。ソルト値に関しては今回は一度のみの生成なので定数にしました。
ユーザー毎に生成するなどの場合は毎回異なるソルト値を生成して記録しておく必要があります。

public function generate($message) {

    $hash = '';
    for($i=1; $i<=$this -> stretch_count; $i++) {
        $hash = hash('sha256', $message.$this -> salt.$hash);
    }

    return $hash;
}

ストレッチングの回数は多いほどいいとされていますが、サーバーのスペックなどもありますので1000回〜数万回程度繰り返します。

ハッシュ値を生成していきます。
引数($message)でデータを受取り、予め設定したストレッチングの回数を元に繰り返していきます。ハッシュ化をする毎に、データとソルト値、生成されたハッシュ値を結合して1つの文字列にしてハッシュ化をしていきます。アルゴリズムはSHA-256を使います。

echo $hash;
// -> 2db0ab40700f1e4aa601a67b9b4aba4a5d86532ec686a14dde4fc5f3c5390357

これでハッシュ値が生成されました。

HMAC

次はHMACでのやりかた。

protected $secret_key = 'pt49fw8fcnwu4tej6i7776utyparpw';

鍵を設定します。

public function generate($message) {
    $hash = hash_hmac('sha256', $message, $this -> secret_key);
    return $hash;
}

SHA-256のアルゴリズムを設定し、ハッシュ化の元の値となる引数($message)と鍵を指定して実行するとハッシュ値が生成されます。

echo $hash;
// -> 091223a45f9841fde79ee597354f8cbbc56669ef185a164bd6991aa9c4e68224

参考記事・本

>> Salt と HMAC の違い
>> 暗号化とハッシュ化に関する基本的な事柄まとめ
>> hash_hmac()の使い方
>> パスワードのハッシュ化

PHP
PHP