Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

塩を一振り(HashとSalt)

More than 1 year has passed since last update.

はじめに

同じハッシュアルゴリズムを採用してる場合、同じデータは必ず同じハッシュ値になります。
これはもちろん一方向ハッシュのメリットなのですが、ログインが必要なサイトでパスワードをハッシュして保存してる場合など、そのままだとよろしくない。

なぜよろしくないか

  • aさんとbさんがたまたまXというパスワードを用いた場合に同じハッシュとなる。
  • aさんのパスワードが判明したら自動的にbさんのパスワードが判明する。
  • もしくはXというパスワードとYというパスワードが同じハッシュ値を得る場合でも片方がわかればもう片方のパスワードが判明したことと同じになる

対策

そこで、ハッシュしたいデータにランダムなデータを追加した物をハッシュし、ランダムなデータはハッシュ値の頭にでも追加するようにしておきます。

以下、PHPによるサンプルです。

hash-test.php
<?php

$hash = makeHash();
var_dump("hash: {$hash}");
var_dump('verify: '.(verify($hash) ? 'true' : 'false'));

function makeHash()
{
    $salt = random_int(0, 65535);
    $hash = sprintf("%04x", $salt).md5($salt.date('Y-m-d'));
    return $hash;
}

function verify($hash)
{
    $salt = substr($hash, 0, 4);
    $salt = hexdec($salt);
    $hash = substr($hash, 4);
    return $hash === md5($salt.date('Y-m-d'));
}

これを実行すると以下のようになり、同一日付で実行している限り、同じデータでもハッシュ値は異なり、さらに照合は正しく行われることが確認できました。

$ php hash-test.php 
string(42) "hash: a90af0b9e2bbd0816ef8770ddf23867be8e2"
string(12) "verify: true"
$ php hash-test.php
string(42) "hash: b03c7eab59127e732f142d0d0abf5093a64d"
string(12) "verify: true"
$ php hash-test.php
string(42) "hash: 61cca0c2296cc8492214b5c8275d43060bd2"
string(12) "verify: true"
$ php hash-test.php
string(42) "hash: 116dda65929e79f330d3149e4773ec85b1e2"
string(12) "verify: true"

実は

PHPの場合はpassword_hashという便利な関数がありますので、それを利用しましょう。

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