web-dev-qa-db-ja.com

MySQLの安全なランダム文字列ジェネレータ

MySQLでパスワードをリセットするための暗号化された安全な文字列を生成したいと考えています。私はこれをPHPのアプリケーションレベルで実行できることを知っています。しかし、それにはOpenSSL拡張機能が必要ですが、私の顧客の多くは持っていない可能性があります。

MySQL 5で広く利用できる安全な方法でそれを行うことができれば理想的です。これは可能ですか?

注:これは、パスワードをリセットするための安全なトークンを生成するためのものです。安全な接続とは何の関係もないため、httpsの使用は解決策ではありません。

5
Chris Muench

MySQLでは、多くの encryption メソッドを使用できます。

双方向の暗号化が必要な場合は、 _aes_encrypt_ を使用できます _aes_decrypt_

安全なハッシュだけが必要な場合は、 _sha2_ を使用できます

次のステートメントは、 _openssl_random_pseudo_bytes_ と同様の結果を得ることができます。

_SELECT HEX(SHA2(CONCAT(NOW(), Rand(), UUID()), 512));
_

上記のステートメントはNOW()を受け取り、それをRand()およびUUID()と連結してから、結果に対して512ビットのSHA2()暗号化を実行します。次に、それをHEX()に変換します

2
Tim Penner

これはMySQLの乱数ジェネレータです。

double my_rnd(struct Rand_struct *Rand_st)
{
    Rand_st->seed1= (Rand_st->seed1*3+Rand_st->seed2) % Rand_st->max_value;
    Rand_st->seed2= (Rand_st->seed1+Rand_st->seed2+33) % Rand_st->max_value;
    return (((double) Rand_st->seed1) / Rand_st->max_value_dbl);
}

外部から大きなランダムな値を渡す必要があります。一意であることが保証されている512ビットの乱数が必要だとします。これで十分かもしれません:

sha2(concat(now(),Rand(),gibberish512,id),512)

Gibberish512が、すべて数ミリ秒以内に多くの値でRandを呼び出すストアドプロシージャへの引数であり、タイムスタンプがそうであったときにタイムスタンプが提供するとします。 MySQL Rand()はそれ自体で64ビット未満のエントロピーを持っています。外部からランダムな引数を渡す(ランダムタイプ、サイコロ、または適切な暗号ランダムprngなどから生成される)。

0
Rob
BEGIN

declare r tinytext;
declare s tinytext default '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
declare n int;

set r='';

while length(r)<=16 do
    set n=Rand() * 61;
    set r=concat(r,substr(s,n,1));
end while;

select r;

END
0
Cris