ハッシュ関数とソルト
先日あるapiを使うにあたって、ハッシュ関数とソルトを使わなければならない機会がありました。
よく分かっていなかったため調べてみました!
ハッシュ関数とは
ある文字列を、決まった長さの新しい文字列に変える関数です。
元の文字列が似たような値でも、ハッシュ関数を通した後は全く似てない値となります。
同じハッシュ関数を使えば、入力されたデータの長さに関係なく、必ず同じ長さのハッシュ値となります。
以下のリンクでは具体的なハッシュ関数の種類を生成される文字数ごとにまとめてくれていました!
ソルトとは
ハッシュ化する前のパスワードに付け足す文字列のことです。
パスワードをよりバレにくくするためにソルトを付け加えます。
※ハッシュ化するだけだと、ハッシュ化された値から元の文字列を求めることはできなくても以下のように試されてバレてしまうことがあるらしいです。
irb(main):007:0> hash1 = "7e263eb7439f020a8e60f454fcd8193ffc071d9f7d54f7260073a4ee8458c23b"
=> "7e263eb7439f020a8e60f454fcd8193ffc071d9f7d54f7260073a4ee8458c23b"
irb(main):008:0> hash2 = Digest::SHA256.hexdigest("test1235")
=> "7e263eb7439f020a8e60f454fcd8193ffc071d9f7d54f7260073a4ee8458c23b"
irb(main):009:0> hash1 == hash2
=> true # hash1の元の値はhash2の元の値と同じ!!
Rubyでハッシュ関数を使ってみる
Rubyでは、Digest::Baseクラスを使ってハッシュ関数を使うことができるようです!
MD5のハッシュ関数を使うなら、以下のようにすれば可能です!
irb(main):001:0> require "digest/md5"
=> true
irb(main):003:0> Digest::MD5.hexdigest("test1234")
=> "16d7a4fca7442dda3ad93c9a726597e4"
同じようにSHA256を使うこともできます!
irb(main):004:0> require 'digest/sha2'
=> true
irb(main):005:0> Digest::SHA256.hexdigest("test1234")
=> "937e8d5fbb48bd4949536cd65b8d35c426b80d2f830c5c308e2cdec422ae2244"
きちんと”test1234”と"test1235"の1文字違いでもハッシュ化した値はかなり違う値になっています!
irb(main):004:0> Digest::SHA256.hexdigest("test1235")
=> "7e263eb7439f020a8e60f454fcd8193ffc071d9f7d54f7260073a4ee8458c23b"
irb(main):005:0> Digest::SHA256.hexdigest("test1234")
=> "937e8d5fbb48bd4949536cd65b8d35c426b80d2f830c5c308e2cdec422ae2244"
Railsでのパスワードハッシュ化
普段、Railsで認証周りにdeviseなどのgemを使っていれば、パスワードにソルトを足してハッシュ化して・・・といったことをgem側でやってくれているようです!
感想その他
今まで「パスワードを平文で保存はマズイ」といったことをよく耳にすることはあったのですが、
平文じゃなく正しく保存する方法はどんなものなのかよく分かっていませんでした。
しかし、今回ハッシュ関数とソルトを調べたことでなんとなく理解することができました。
また、devise gem、本当に色々なことやってくれていて凄いなと思いました。。。!!