暗号学における「塩値Salt」

4954 ワード

テキストリンク:http://www.libuchao.com/2013/07/05/password-salt
なぜパスワードに「塩」を入れるのか
塩(Salt)
暗号学では、暗号の任意の固定位置に特定の文字列を挿入することで、ハッシュ後の結果と元の暗号を用いたハッシュ結果が一致しないようにするプロセスを「塩を加える」と呼ぶ.
以上の言葉はWikipediaでSaltの定義ですが、この言葉だけではSaltとは何か、そして何の役割を果たしているのか理解しにくいです.
第1世代のパスワード
初期のソフトウェアシステムやインターネットアプリケーションでは、データベースにユーザーテーブルを設計する際に、大体このような構造がありました.
mysql> desc User;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| UserName | varchar(50)  | NO   |     |         |       |
| PassWord | varchar(150) | NO   |     |         |       |
+----------+--------------+------+-----+---------+-------+

データストレージの形式は次のとおりです.
mysql> select * from User;
+----------+----------+
| UserName | PassWord |
+----------+----------+
| lichao   | 123      |
| akasuna  | 456      |
+----------+----------+

主なキーフィールドはこの2つで、1つはログイン時のユーザー名で、対応するパスワードで、その時のユーザー名は明文で保存されています.ログイン時のユーザー名が123であれば、データベースに保存されているのは123です.この設計は非常に簡単ですが、データベースが漏洩すると、すべてのユーザー名とパスワードが漏洩し、深刻な結果になります.『CSDN詳細解600万ユーザーパスワード漏洩の始末』を参照してください.
第2世代パスワード
第1世代の暗号設計の欠陥を回避するために、賢い人はデータベースの中で明文の暗号を記憶しないで、暗号化後の暗号を記憶して、典型的な暗号アルゴリズムはMD 5とSHA 1で、そのデータテーブルは大体このように設計されています:
mysql> desc User;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| UserName | varchar(50)  | NO   |     |         |       |
| PwdHash  | char(32)     | NO   |     |         |       |
+----------+--------------+------+-----+---------+-------+

データストレージの形式は次のとおりです.
mysql> select * from User;
+----------+----------------------------------+
| UserName | PwdHash                          |
+----------+----------------------------------+
| lichao   | 202cb962ac59075b964b07152d234b70 |
| akasuna  | 250cf8b51c773f3f8dc8b4be867a9a02 |
+----------+----------------------------------+

パスワードが123の場合、データベースには202 cb 962 ac 59075 b 964 b 07152 d 234 b 70または40 bd 001563085 fc 35165329 ea 1 ff 5 c 5 ecbdbbeefが格納されます.ユーザがログインすると,ユーザが入力したパスワードをMD 5(またはSHA 1)実行してデータベースと比較し,ユーザのアイデンティティが正当であるか否かを判断する暗号アルゴリズムをハッシュと呼ぶ.
厳密には、このアルゴリズムは暗号化とは言えない.理論的には復号できないからだ.したがって、データベースが失われても、データベース内のパスワードは暗号化されているため、ユーザーの元のパスワードを判断することはできません.そのため、結果はそれほど深刻ではありません.
第3世代のパスワード
もともと第2世代のパスワードの設計方法はすでにとても良くて、あなたのパスワードの設定が少し複雑でさえすれば、ほとんど解読される可能性はありません.しかし、パスワードの設定が複雑でなければ、解読される可能性は高いです.
良い人はよく使うパスワードを収集して、それから彼らに対してMD 5あるいはSHA 1を実行して、それから1つのデータ量のとても巨大なデータ辞書を作って、それから漏洩したデータベースの中のパスワードに対して対比して、もしあなたの原始のパスワードが不幸にもこのデータ辞書の中に含まれているならば、そんなに長くかかりませんあなたの原始のパスワードをマッチングすることができます.このデータ辞書は簡単に収集でき、CSDNが漏らした600 wのパスワードは、とても良い原始素材です.
そこで、第3世代のパスワード設計方法が誕生し、ユーザーテーブルには次のフィールドが追加されました.
mysql> desc User;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| UserName | varchar(50) | NO   |     |         |       |
| Salt     | char(50)    | NO   |     |         |       |
| PwdHash  | char(32)    | NO   |     |         |       |
+----------+-------------+------+-----+---------+-------+

データストレージの形式は次のとおりです.
mysql> select * from User;
+----------+----------------------------+----------------------------------+
| UserName | Salt                       | PwdHash                          |
+----------+----------------------------+----------------------------------+
| lichao   | 1ck12b13k1jmjxrg1h0129h2lj | 6c22ef52be70e11b6f3bcf0f672c96ce |
| akasuna  | 1h029kh2lj11jmjxrg13k1c12b | 7128f587d88d6686974d6ef57c193628 |
+----------+----------------------------+----------------------------------+

Saltは任意のアルファベット、数字、またはアルファベットまたは数字の組み合わせであってもよいが、ランダムに生成されなければならず、ユーザごとにSaltが異なり、ユーザ登録時にデータベースに格納されるのは明文パスワードではなく、単純に明文パスワードをハッシュするのではなく、MD 5(明文パスワード+Salt)である.
MD5('123' + '1ck12b13k1jmjxrg1h0129h2lj') = '6c22ef52be70e11b6f3bcf0f672c96ce'
MD5('456' + '1h029kh2lj11jmjxrg13k1c12b') = '7128f587d88d6686974d6ef57c193628'

ユーザがログインするときも,同様にこのアルゴリズムで検証する.
Saltが追加されたため、データベースが流出しても、パスワードはSaltが追加された後のハッシュであるため、悪人のデータ辞書は直接一致せず、明文パスワードが解読される確率も大幅に低下している.
Saltを入れたら絶対に安全なのではないでしょうか.淡々としてない!悪い人たちは、データ辞書のパスワードに加えて、データベースのSaltを漏らしてハッシュしてマッチングすることができます.しかし、私たちのSaltはランダムに発生しているので、もし私たちのユーザーのデータテーブルに30 wのデータがあれば、データ辞書には600 wのデータがあります.悪い人たちが完全にカバーしたい悪い人は、Saltを加えてからハッシュするデータ辞書のデータ量は30000*600000=180000000000、1兆8000億ですね.悪いことをするコストが高すぎるでしょう.しかし、あるユーザーのパスワードを解読したいだけなら、この600 wのデータにSaltを加えてハッシュマッチングするだけです.Saltは安全係数を大幅に向上させたが,絶対安全ではないことがわかる.
実際のプロジェクトでは、Saltは必ずしも一番前や一番後ろに追加する必要はありません.真ん中に挿入してもいいですか.別々に挿入してもいいし、逆順序にしてもいいです.プログラム設計時に柔軟に調整することができ、解読の難易度を指数級的に増加させることができます.
PS、文の中でいわゆる第1、2、3世代のパスワードの呼び方、私自身YYのです.