ハッシュ関数とソルト

先日あるapiを使うにあたって、ハッシュ関数とソルトを使わなければならない機会がありました。

よく分かっていなかったため調べてみました!

 

 

ハッシュ関数とは

ある文字列を、決まった長さの新しい文字列に変える関数です。

元の文字列が似たような値でも、ハッシュ関数を通した後は全く似てない値となります。

同じハッシュ関数を使えば、入力されたデータの長さに関係なく、必ず同じ長さのハッシュ値となります。

以下のリンクでは具体的なハッシュ関数の種類を生成される文字数ごとにまとめてくれていました!

qiita.com

 

ソルトとは

ハッシュ化する前のパスワードに付け足す文字列のことです。

パスワードをよりバレにくくするためにソルトを付け加えます。

※ハッシュ化するだけだと、ハッシュ化された値から元の文字列を求めることはできなくても以下のように試されてバレてしまうことがあるらしいです。

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クラスを使ってハッシュ関数を使うことができるようです!

docs.ruby-lang.org

 

 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側でやってくれているようです!

qiita.com

qiita.com

 

 

感想その他

今まで「パスワードを平文で保存はマズイ」といったことをよく耳にすることはあったのですが、

平文じゃなく正しく保存する方法はどんなものなのかよく分かっていませんでした。

しかし、今回ハッシュ関数とソルトを調べたことでなんとなく理解することができました。

また、devise gem、本当に色々なことやってくれていて凄いなと思いました。。。!!