5

SQLでパスワードをソルティングする質問があります:

以下のコードは、10 文字の文字列をランダムに生成して特定のパスワードをソルトします。

Update Teacher 
SET    TeacherSalt = SUBSTRING(MD5(RAND()), -10), 
       TeacherPassword = SHA1(CONCAT('009b9b624aaecc4b3217dcd4bfee15ab704745d7',SUBSTRING(MD5(RAND()), -10)))
WHERE TeacherPassword = '009b9b624aaecc4b3217dcd4bfee15ab704745d7'

しかし、私の質問は、ソルトが生成する文字列がこれらすべての文字から得られるようにソルトを変更したいということです。

./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

キャラクターは63人。これを行うphpの方法は次のとおりです。

$salt = ""; 
for ($i = 0; $i < 40; $i++) { 
   $salt .= substr(
     "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 
     mt_rand(0, 63), 
     1); 
}

しかし、これを上記のSQLの方法でどのように書くことができますか?

4

4 に答える 4

6

MySQL で実行できます。ただし、ランダムな単語生成はそれほどきれいではありません。塩の生成と適用に関しては、その部分は難しくありません。

2 つのステートメントを使用して、最初に全員のソルトを生成し、次にそれらを適用します。(注: 本当に 1 つのアカウントにのみ適用する場合は、WHERE 句を追加してください。)

mysql> select * from salty;
+------+------+------+
| id   | pw   | salt |
+------+------+------+
|    1 | fish | NULL |
|    2 | bird | NULL |
|    3 | fish | NULL |
+------+------+------+

(ユーザー 1 と 3 はたまたま同じパスワードを持っていることに注意してください。ただし、一度ソルト化してハッシュ化すると、それらが同じになることは望ましくありません。)

mysql> update salty set salt=SUBSTRING(MD5(RAND()), -10);

mysql> select * from salty;
+------+------+------------+
| id   | pw   | salt       |
+------+------+------------+
|    1 | fish | 00fe747c35 |
|    2 | bird | ee4a049076 |
|    3 | fish | 6a8285f03c |
+------+------+------------+

(注: 特定のアルファベットのバージョンは後で示します)

mysql> update salty set pw=sha1(concat(pw,salt));

mysql> select * from salty;
+------+------------------------------------------+------------+
| id   | pw                                       | salt       |
+------+------------------------------------------+------------+
|    1 | ac1b74c36b4d2426460562e8710bd467bd034fc8 | 00fe747c35 |
|    2 | d63d035f9cac1ac7c237774613b8b702d8c227df | ee4a049076 |
|    3 | 6a0b1e36f489ef959badf91b3daca87d207fb5de | 6a8285f03c |
+------+------------------------------------------+------------+

2 つのステートメントがあり、各行は一意にソルト化およびハッシュ化されています。

指定されたアルファベットの単語をランダムに生成するために、ELT() には醜いトリックがあります。64 文字のアルファベットの 10 文字の単語の場合:

UPDATE salty SET salt=CONCAT(
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64),  
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9'),
  ELT(1+FLOOR(RAND()*64), 
  '.','/',
  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  '0','1','2','3','4','5','6','7','8','9')
)

mysql> select * from salty;
+------+------+------------+
| id   | pw   | salt       |
+------+------+------------+
|    1 | fish | TzHO0e5I/k |
|    2 | bird | 65xLptoDZ3 |
|    3 | fish | JNok/SfmkG |
+------+------+------------+    

恐ろしいですね。しかし、単一の MySQL ステートメントでそれを行うと、特に数百万のレコードを持つテーブルに適用する必要がある場合に、PHP でループして行ごとに 1 つ (または 2 つ) のクエリを作成するよりもはるかに高速になる場合があります。一度に何百万ものクエリを作成するのではなく、1 つの醜いクエリを作成します。

しかし、他の人が言うように、SHA1 はもはや十分なハッシュではありません。

大量のレコードがある場合は、そのような MySQL クエリをいくつか使用して、暫定的な解決策として SHA2 を使用するようにすべてのレコードを更新し、PHP を使用して時間の経過とともにそれらをより強力なハッシュに個別に更新することが理にかなっている場合があります。もちろん、特定のレコードがどのハッシュを使用したかを知る方法が必要です。

補足として、(例のように) 1 つの行のみを更新する場合、MySQL 変数を使用して、行の 2 つの列を更新するのに十分な長さのランダムに生成された文字列を一時的に保持できます。

mysql> SET @salt=SUBSTRING(MD5(RAND()), -10); UPDATE salty SET salt=@salt,pw=SHA1(CONCAT(pw,@salt)) WHERE id=2; SET @salt=NULL;

このようにして、@salt の同じ値がソルトの設定と pw 計算の両方に使用されます。ただし、複数の行の更新では機能しません (それらはすべて同じソルトになってしまいます)。

于 2012-11-02T01:06:20.727 に答える
3

本当にランダムにソルトしたい場合は、php でランダムなソルトを生成し、そのソルトでパスワードを暗号化し、テーブルの 2 つのフィールドにソルト キーとパスワードの両方を保存することによってのみ実行できます。テーブルにはソルト フィールドとパスワード フィールドが必要です。ただし、mysql を使用して暗号化を行いたい場合は、ここを参照してくださいhttp://dev.mysql.com/doc/refman/5.5/en//encryption-functions.html

ユーザーのログイン資格情報を検証するときは、同じプロセスに従いますが、今回のみ、新しいランダムなものを生成する代わりに、データベースからソルトを使用します。ユーザーが提供したパスワードをそれに追加し、ハッシュ アルゴリズムを実行してから、その結果をそのユーザーのプロファイルに保存されているハッシュと比較します。

以下のリンクから、さらにアイデアが得られるかもしれません。

ユーザーのパスワードとソルトを MySQL に安全に保存するにはどうすればよいですか?

ソルト弦はどこに保管していますか?

ソルトされた SHA512 と比較して、ソルトされた SHA1 はどれほど安全でないか

Salt Generation とオープンソース ソフトウェア

あなたが今アイデアを得たことを願っています。

于 2012-10-22T03:09:23.127 に答える
1

簡単に言えば、phpでそれを解決します。最初にテーブルから情報を取得します (一意ではない可能性があるパスワードではなく、自動インクリメント ID を使用して行を選択してください)。

     function makeMeASalt($max=40){
         $i = 0;
         $salt = "";
         $characterList = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
         while ($i < $max) {
            $salt .= $characterList{mt_rand(0, (strlen($characterList) - 1))};
            $i++;
         }
         return $salt;
     }

     $hash=crypt($password.makeMeASalt(40))

     $query="Update Teacher 
         SET TeacherSalt = '".$salt."', TeacherPassword = ".$hash."
         WHERE TeacherID = '".$teacherid."'";
     mysql_query($query) or die(mysql_error())

これはまた、あなたの塩がフィールド間で同じではないという、すでに言及された問題を取り除きます!

于 2012-11-01T12:25:27.593 に答える