LoginSignup
2
0

More than 3 years have passed since last update.

塩を一振り(HashとSalt)

Posted at

はじめに

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

なぜよろしくないか

  • 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という便利な関数がありますので、それを利用しましょう。

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