LoginSignup
69
44

ハッシュ化のソルト(salt)とペッパー(pepper)についてまとめた

Last updated at Posted at 2021-12-08

はじめに

業務で上司が書いたハッシュ化のコードの中に**"salt"**という記述がありました。
**「パスワードに塩をかけるとはどういうこと?」**と思い、調べてみたら意外と奥が深かったのでまとめました。
塩

対象者

この記事は下記のような人を対象にしています。

  • 駆け出しエンジニア
  • プログラミング初学者
  • ログインまわりを初めて実装する人
  • PHPのmd5関数を使ってる人

結論

パスワードの漏洩対策に使用されるハッシュ化ですが、**ソルト(salt)やペッパー(pepper)**という手法を用いるとより安全に運用できます。

不安 まぁまぁ安心 より安心
ハッシュ化のみ ハッシュ化+ソルト(salt) ハッシュ化+ソルト(salt)+ペッパー(pepper)

本記事ではスコープ外なので解説しませんが、実用上はストレッチングも用いたほうが良いです。

ハッシュ化とは

ハッシュ化とは、元データ(文字列)をハッシュ値(文字列)に不可逆変換することを指します。
ハッシュ化を実行する関数をハッシュ関数と呼びます。
ハッシュ関数は様々な種類があり、md5やsha-256,sha-512,bcryptなどが有名ですが、今回はmd5を使用します!

md5関数を使用した例を下記に示します。

example.php
<?php
print ('ガンダム: '.md5('ガンダム')."\n");
print ('ガンキャノン: '.md5('ガンキャノン')."\n");
print ('ガンタンク: '.md5('ガンタンク')."\n");
?>

//結果
ガンダム: e87f1086f7bf9f59f1ec0b2dd2f320a4
ガンキャノン: e44e4ca716d4df9d1d4553641f77a00c
ガンタンク: 7faab3c51029273da3ee78d36e82f788

ハッシュ化の特徴

パスワードをユーザーテーブルに保存することが多いと思いますが、パスワードの文字列をそのまま保存すると**漏洩した場合に大変なことになります。**
ハッシュ化は不可逆なので、**「ハッシュ値から元のパスワードを復元することはできない」**ことが特徴です。
そのため、パスワードそのものではなく、ハッシュ値をテーブルに保存することで、漏洩時のリスクを減らすことができます。

ハッシュ化の課題

とはいえ、ハッシュ化にも課題があります。
不可逆変換とはいえ、入力値に対して出力されるハッシュ値は決まっているので、レインボーテーブル攻撃という手法でパスワードを特定することができます。
ユーザーが"123456"や"password"のようなイージーなパスワードを使用している場合、簡単に特定されてしまう恐れがあります。

ハッシュ化のソルト(salt)とは

ハッシュ化の課題(レインボーテーブル攻撃)を回避するために、ソルト(salt)という手法があります。
ソルト(salt)は元データ(文字列)に任意の文字列を加えてハッシュ化する手法です。

example.php
<?php
$salt = "mySalt";
print ('123456(ソルトなし): '.md5('123456')."\n");
print ('123456(ソルトあり): '.md5('123456'.$salt)."\n");
?>

//結果
123456(ソルトなし): e10adc3949ba59abbe56e057f20f883e
123456(ソルトあり): b8d06f590de08403b61e9ef59b81ad33

"123456"のようなよく使われるパスワードでもソルトを使用することで、異なるハッシュ値に変換され、レインボーテーブル攻撃対策になります。

ハッシュ化のソルト(salt)の課題

万能そうに見えるソルト(salt)にも課題があります。
それは**「ソルト(salt)はパスワードのハッシュ値と同じテーブルに保存されることが多い」**ということです。
データが漏洩する場合、ハッシュ値とセットでソルト(salt)も漏洩している場合が多いでしょう。
漏洩したソルト(salt)を使って簡単にハッシュ値からパスワードを特定できてしまうのです。

ハッシュ化のペッパー(pepper) / シークレットソルト(secret salt)とは

同時に漏洩しないように、ハッシュ値とは別に階層(.env等)にソルトを保存する手法をペッパー(pepper)と呼びます。
ソルト(salt)と別物のように聞こえますが、シークレットソルト(secret salt)という呼び方もあります。
ハッシュ値と別の階層に保存されているため、同時に流出することがありませんので、リスクを低減できます。

実際の使用例を下記に示します。

.env
#.env
MYPEPPER = "myPepper"
example.php
<?php
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

$pepper = $_ENV["MYPEPPER"]; // .envからペッパー読込
print ('123456(ペッパーなし): '.md5('123456')."\n");
print ('123456(ペッパーあり): '.md5('123456'.$pepper)."\n");
?>

// 結果
123456(ペッパーなし): e10adc3949ba59abbe56e057f20f883e
123456(ペッパーあり): e1b76e76809f8c5d59b279b37fa2acd2

.envからペッパーを読み込んで、ハッシュ化できていますね!

おわりに

ハッシュ化をさらに堅牢にするソルト(salt)とペッパー(pepper)についてまとめました。
パスワード周りを実装する際には、ハッシュ化だけで満足せずにソルト(salt)やペッパー(pepper)を活用しましょう!

参考記事

パスワードハッシュ化で用いるソルト(Salt)とペッパー(Pepper)/シークレットソルト(Secret Salt)の役割と効果
今さら聞けないハッシュ化
暗号化に用いるSaltの課題を解決するSecret Salt
4枚の図解でわかるレインボーテーブル攻撃

69
44
3

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
69
44