MySQLが生まれたのはこの時期で、プラスマイナス1年です。MySQLには、他の人のデータへのアクセスを許可されるべきではないが、自分のデータにアクセスできるユーザーがいました。
Michael Widenius(または単にMonty)は、偏執的な警備員に直接知っていました。これはそのようなポイントの1つです(ソース、
global.h
)。
/* Paranoid settings. Define I_AM_PARANOID if you are paranoid */ #ifdef I_AM_PARANOID #define DONT_ALLOW_USER_CHANGE 1 #define DONT_USE_MYSQL_PWD 1 #endif
したがって、MySQLのパスワードがクリアテキストで送信されたことがないのは驚くことではありません。 ハッシュに基づくランダムな文字列が渡されました。 具体的には、最初の認証プロトコル(1996年mysql-3.20から引用)は次のように機能しました。
- サーバーはパスワードハッシュを保存しました。 ただし、ハッシュは次のような非常に単純なものでした。
for (; *password ; password++) { tmp1 = *password; hash ^= (((hash & 63) + tmp2) * tmp1) + (hash << 8); tmp2 += tmp1; }
これは、一時的に合計で32ビットです。
- 認証のために、サーバーはランダムな8文字の文字列をクライアントに送信しました。
- クライアントは、この行のハッシュ(上記のハッシュ)とパスワードハッシュを考慮しました。 次に、これら2つの結果の32ビット数のXORが乱数ジェネレーターを初期化し、8つの「ランダム」バイトを生成してサーバーに送信しました。
- 次に、サーバーはパスワードハッシュ(彼が知っている)を取得し、そのランダムな文字列(彼自身が生成した、つまり彼もそれを知っている)のハッシュとXOR-ilしました。 さて、私は私の側で乱数ジェネレータを実行し、クライアントが送信したものと比較しました。
この決定の利点は明らかでした。 パスワードがクリアテキストで送信されたことはありません。 そして、それもオープンな形で保存されませんでした。 しかし、正しい、ハッシュあたり32ビットは1996年でも深刻ではありません。したがって、次のメジャーリリース(mysql-3.21)では、ハッシュは64ビットでした。 この形式では、「old mysql authentication」という名前で、このプロトコルは現在も使用されています。 彼らはMySQL-5.7からそれを切り取ったが、5.6ではまだそこにあり、MariaDBでは10.2にさえある。 現在誰も使用していないことを心から願っています。
* * *
このスキームの主な問題は、2千分の1の領域のどこかでわかったように、パスワードが突然プレーンテキストで保存されることです。 はい、はい。 つまり、パスワードハッシュは保存されますが、クライアントはパスワードを必要としません。ハッシュは認証に使用されます。 つまり、パスワードハッシュを使用して
mysql.user
プレートからドラッグするだけで十分です。クライアントライブラリを
mysql.user
変更した後は、他のユーザーと同じように接続できます。
さて、この自作のハッシュ関数は非常に疑わしいものでした。 その結果、ちなみに壊れていました( sqlhack.com )が、その頃にはすでに新しいプロトコルがありました。
その後、次の目標を持ってそれを発明しました(そして「私たち」は私、 コストヤ 、ピーターツァイツェフ 、および他の数人の仲間でした )。
- サーバーに保存されているものは認証には不十分です
- ワイヤーを介して送信されるものは認証には不十分です
- ボーナス-通常の暗号化ハッシュ関数を使用し、十分なアマチュアアクティビティ
そして、次の「double-SHA1」プロトコルが判明しました。これは、MySQL-4.1に含まれており、未使用のままです。
- サーバーは
SHA1(SHA1(password)).
保管しSHA1(SHA1(password)).
- 認証のために、サーバーはクライアントにランダムな文字列(20文字)を送信します。これは、歴史的に「スクランブル」と呼ばれています。
- クライアントはこの種のものをサーバーに送信します。
SHA1( scramble || SHA1( SHA1( password ) ) ) ⊕ SHA1( password )
ここで、⊕-XOR、および|| -文字列の連結。
- したがって、サーバーは
SHA1(password)
認識しませんが、スクランブルとSHA1(SHA1(password))
を認識します。つまり、このクライアント構成の第1オペランドを計算できます。 次に、XORを使用して、2つ目のSHA1(password)
を取得しSHA1(password)
。 そしてそれから数えて、SHA1は最終的にそれをこのユーザーのテーブルに保存されているものと比較できます。 うわ
プロトコルは成功し、すべての目標が達成されました。 認証を聞くことは役に立たない;パスワードハッシュを引き下げることは役に立たない。 しかし、誰かがパスワードハッシュを使用して
mysql.user
テーブルをプルダウンし、認証をリッスンした場合、軟膏にはまだハエがありました-その後、彼はサーバーがすることを繰り返し、
SHA1(password)
を復元して、将来的に適切なふりをすることができますユーザーごと。 私たちはそれを閉じませんでしたし、公開鍵を使用した暗号化がなければ、原則として閉じないという強い疑いがあります。 ただし、軟膏のこのハエは非常に小さく、ハッシュがある場合、パスワードは辞書から簡単に取得できることがよくあります。
* * *
すべては順調でしたが、残念ながら進歩は止まりません。 MySQLはOracleの管理下に置かれ、MariaDBはスピンオフしてその生命を癒し、これらの混乱にかかわらず、SHA1の信頼性は毎年低下しました。 Oracleで大騒ぎした最初の人。 新しいプロトコルの開発は、クリストファーピーターソン同志に委ねられました。 その時までに私はすでにMariaDBにいたので、彼が何を考え、誰と相談していたかしか推測できません。 しかし、主なことは明らかです-目標はSHA2に切り替えて、軟膏に残っているこの小さなハエを取り除くことでした。 彼は、公開鍵暗号が必要であることを正しく認識しました。 そのため、MySQL 5.7の新しいプロトコルは、SHA256(SHA2の256ビットバージョン)とRSAを使用します。 そして、それはすべてこのように機能します:
- サーバーは
SHA256(password)
- 前と同様に、サーバーは20文字のスクランブルをクライアントに送信します
- クライアントは、事前に保存されたファイルからサーバーのRSA公開キーを読み取ります
- スクランブルによって受信されたクライアントXOR-itパスワード(パスワードが長い場合、スクランブルはループで繰り返されます)、サーバーキーで暗号化して送信します
- サーバーは、それぞれ秘密鍵XOR-itで復号化し、元の開いた形式でパスワードを受け取り、SHA256を考慮して比較します
すべてが非常に簡単です。 私の観点からはマイナスは1つですが、大きなものです。事前にすべてのクライアントにサーバー公開キーを配布するのは非常に不便です。 しかし、まだ多くのサーバーがあり、1つのクライアントがすべてに順番に接続する必要がある場合があります。 このために、おそらく、クライアントはサーバーから公開鍵を要求できるということをMySQLで行いました。 しかし、私たちの困った時代のこのオプションを真剣に考えることはできません-さて、本当に、クライアントが誰かが彼に送ったある種のバイトが実際にサーバーの公開鍵であると信じるのはなぜですか? 中間者はまだキャンセルされていません。 それでも、どういうわけか、サーバーがクリアテキストでパスワードを受け取るのは良くありません。 些細なことですが、不快です。
ただし、MariaDBにはこれさえなく、SHA1しかありませんでした。 銀行は不平を言ったが、原則としてはそれで十分だった。 しかし、 最新のニュースに照らして、ハッシュベテランの代わりを探し始めました。 実際、まだひどいことは何も起きていません-衝突を探すことを学びました。誰かが同じハッシュで2つのパスワードを生成できます。 しかし、これを各ユーザーに説明することはできません。 そして、突然明日、SHA1で他に何が見つかるでしょうか?
* * *
また、公開鍵暗号に基づいた新しいプロトコルを構築しました。 そのため、
mysql.user
、トラフィックの傍受、またはその両方、あるいはサーバーの完全な侵害さえもパスワードを開くことができません。 そして、もちろん、ユーザーの観点からは、すべてが以前のように機能するはずです-パスワードを入力し、アクセスを取得しました。 事前に配布する必要のあるファイルはありません。 プロトコルはed25519に基づいています 。これは、伝説的なダニエルJ.バーンスタイン (または単にdjb)によって発明された楕円曲線を使用した暗号署名です。 彼はすぐに使える実装をいくつか書いており、そのうちの1つはOpenSSHで使用されています。 ちなみに、名前は使用される曲線のタイプ(エドワード曲線)とフィールドの順序2,255 –19に由来します。 通常(opensshおよびどこでも)ed25519は次のように機能します(数学を省略します):
- 32個のランダムバイトが生成されます-これが(ほぼ)秘密鍵になります。
- それらからSHA512が考慮され、その後、数学的な魔法が発生し、公開鍵が取得されます。
- テキストは秘密鍵で署名されています。 署名は公開鍵で検証できます
これに基づいて、MariaDBの新しい認証プロトコルが機能します。
- ランダムな32バイトの代わりに、ユーザーのパスワード(つまり、パスワードは実際には秘密キーです)を取得し、その後、通常どおりSHA512と公開キーの計算を取得します。
- サーバーでは、 公開鍵はパスワードとして
mysql.user
保存されます(base64では43バイト) - 認証のために、サーバーはランダムな32バイトのスクランブルを送信します
- 顧客が署名する
- サーバーが署名を検証する
以上です! SHA1よりもさらに簡単です。 実際、欠点はまだ明らかになっていません。パスワードはサーバーに保存されず、転送されず、サーバーはいつでもそれを見ることはなく、復元することはできません。 中間者は休んでいます。 キーを持つファイルはありません。 当然、パスワードはブルートフォースになる可能性があります。ここでは何もできません。パスワードを完全に拒否するだけです。
この新しいプロトコルは、MariaDB-10.1.22で別個のプラグインとして最初に登場しました。10.2または10.3では、より緊密にサーバーに統合されます。