バージョン4.1より前のMySQLパスワードに使用されているパスワードハッシュ(現在はOLD_PASSWORD()
と呼ばれています)は、ソルトや反復カウントのない非常に単純なアドホックハッシュのようです。 Python at Django snippets:Old MySQL Password Hash の実装を参照してください==
暗号化されていますか?壊れた?
私がウェブ上で目にするのは、総当たり攻撃です。これらは、予想どおり、短い長さから中程度の長さのパスワードで非常に成功しています。このアドホックアルゴリズムのブルートフォースは、SHA1(2回)を単に使用する新しいPASSWORD()
関数への攻撃よりも遅いのかと思いますが、SHA1のハードウェアアクセラレーションサポートが広まっていると思います。 MySQLパスワードに対する欠陥と攻撃の詳細については 無塩ハッシュを使用した有名なアプリの例を見る
MySQL OLD_PASSWORD()
で公開されている暗号解読については知りませんが、非常に弱いため、一種のジョークです。これは、暗号化コースの練習問題として与えることができます。
更新:下記のミートインザミドルと同様の暗号解読が F. MullerとT. Peyrinに公開されました情報セキュリティと暗号学に関する国際会議の「T関数ベースのハッシュ関数の暗号解析」-ICISC 2006 2006年、より一般的な説明と短いパスワードを見つけてRAMに保持するためのいくつかの最適化。
たとえば、内部状態を「元に戻す」Cコードは次のとおりです。
_static int
oldpw_rev(uint32_t *pnr, uint32_t *pnr2, uint32_t add,
unsigned char *cc, unsigned len)
{
uint32_t nr, nr2;
uint32_t c, u, e, y;
if (len == 0) {
return 0;
}
nr = *pnr;
nr2 = *pnr2;
c = cc[len - 1];
add -= c;
u = nr2 - nr;
u = nr2 - ((u << 8) ^ nr);
u = nr2 - ((u << 8) ^ nr);
nr2 = nr2 - ((u << 8) ^ nr);
nr2 &= 0x7FFFFFFF;
y = nr;
for (e = 0; e < 64; e ++) {
uint32_t z, g;
z = (e + add) * c;
g = (e ^ z) & 0x3F;
if (g == (y & 0x3F)) {
uint32_t x;
x = e;
x = y ^ (z + (x << 8));
x = y ^ (z + (x << 8));
x = y ^ (z + (x << 8));
nr = y ^ (z + (x << 8));
nr &= 0x7FFFFFFF;
if (oldpw_rev(&nr, &nr2, add, cc, len - 1) == 0) {
*pnr = nr;
*pnr2 = nr2;
return 0;
}
}
}
return -1;
}
_
この関数は、_cc[]
_配列(len
と_nr2
_、2つの31ビットワード、およびパスワード文字の合計であるnr
値)で指定されたadd
パスワード文字の後に内部状態が指定された場合、nr
および_nr2
_beforeの有効なソリューションを計算して、パスワード文字の挿入を行います。これは効率的です。
これは、簡単なミドルインザミドル攻撃につながります。 14個の小文字のシーケンスASCII文字で、各文字の後にその補数が続く(「a」の補数は「z」、「b」の補数は「y」、このようなシーケンスは約80億個あります。これらのシーケンスの文字の合計は常に固定値1533であることに注意してください。[~#~]n[~#~それらのシーケンスの];それらのそれぞれについて、OLD_PASSWORD()
を使用して対応するハッシュを計算し、大きなファイルに値を蓄積します。各エントリには、文字のシーケンスと対応するnr
および_nr2
_。次に、62ビットのnr
/_nr2
_ペアでファイルを並べ替えます。このファイルは、次のような大きなテーブルです。「thisシーケンスを使用して、that内部状態への初期値」。
次に、[〜#〜] n [〜#〜]シーケンスを再び取り、今回は実際のコードを使用して、それぞれにoldpw_rev()
(上記のように) nr
および_nr2
_の開始点としてハッシュを攻撃し、add
の場合は2 * 1533 == 3066。これにより、[〜#〜] n [〜#〜]他のペアnr
/_nr2
_が得られ、それぞれに対応するシーケンスがあります。これらの値は別のファイルに蓄積され、再び62ビットのnr
/_nr2
_ペアでソートします。この2番目のファイルは、「thisシーケンスをthat内部状態で使用して、現在攻撃しているハッシュ値を取得する」という大きな表です。
その時点で、2つの一致するペア、つまり、最初のファイルと2番目のファイルで同じnr
/_nr2
_を見つける必要があります。対応する14文字のシーケンスは、ハッシュ出力に一致する28文字のパスワードの2つの半分になります。それはおそらく最初にnotで使用されたパスワードですが、これは同じ値にハッシュされ、MySQLによって受け入れられるパスワードです。[〜#〜] n [〜#〜]が20億程度に達すると、一致するペアが得られる可能性が高くなります(サイズ2のスペースにいます)62、[〜#〜] n [〜#〜]がsqrt(262))。
この攻撃には2程度の作業要素があります37(並べ替えステップの説明)、2よりもはるかに小さい6262ビット出力のハッシュ関数で理論的に達成できる作業係数(すでに適切なセキュリティには低すぎる)。したがって、OLD_PASSWORD()
関数は暗号的に壊れています。
(おそらくそれよりはるかに優れた攻撃があります。)
私は昨日google-fuを磨きましたが、今回はこれについて2006年の論文を見つけることができました。 F。ミューラーとT.ペイリン「情報セキュリティと暗号学に関する国際会議-ICISC 2006 」の「T関数ベースのハッシュ関数の暗号解析」。すごい仕事!
しかし、それが説明する関数は実際のMySQL OLD_PASSWD(別名libmysql/password.c hash_password())とは少し異なるため、両者の間の衝突はまったく機能しません。
この論文では、「パスワードを選択すると、「MySQL123」と表示されます。パスワードのハッシュは(nk1&K = 0x1b03947c 、nk2&K = 0x1d6d177b)、K = 0x3fffffff。 "で、RGp0mA23のハッシュは同じであると言います。
だが:
mysql> select OLD_PASSWORD('MySQL123');
+--------------------------+
| OLD_PASSWORD('MySQL123') |
+--------------------------+
| 1b03947a6f1ae59b |
+--------------------------+
対RGp0mA23の1b03947a77350d71。
そのため、MySQL OLD_PASSWORDに対処するために、まだ少し作業が必要です。
とにかく、MySQLのデフォルトのパスワードハッシュ(古いものでも新しいものでも)の使用を中止し、少なくとも "cryptと同等の技術を使用してください。 " 1978年にUnixからソルトとイテレーションカウントを使って...
CVE-2003-148 MySQLのOLD_PASSWORDハッシュ関数に対して発行されました。アドバイザリから主な懸念はそのが速すぎることです。 MySQL開発チームの観点から、データベースへの負荷を可能な限り削減したい方法を理解できます。ダブルsha1の使用は、キー強化の取り組みです。正直に言うと、ダブルsha1はまだ非常に高速であり、2回実行するだけでCVEを緩和できます。