5

最初の注意:これは個人的ないじくり回しプロジェクトのためだけのものです。私はここでエンタープライズセキュリティを書いているのではありません。もしそうなら、私は自分のスキームを書こうとするよりもよく知っているでしょう。:-D

編集:上記の点を強調するために、これを「iKnowThisWouldBeABadIdeaInRealLife」でタグ付けしようとしましたが、25文字を超えていたためSOは受け入れませんでした。私はそれが商用グレードではないことを知っていることに注意してください!

HTTP経由でユーザーを認証する方法が必要です(この場合はHTTPSを使用できません)。私は、相手が本当に彼らが言っている人であるということを知る必要があります(ある程度の自信を持って)。ユーザーが正当であると確信したら、クライアントとサーバー間のコンテンツがプレーンテキストとして送信されるかどうかは気にしません。

私が見ている問題は、パスワードをプレーンテキストとして送信せずにクライアントからサーバーに送信しようとすることです。一部のGoogle検索で見栄えの良いライブラリが見つかったため、JavaScriptで公開鍵暗号を試すことを考えました。

これが私が考えているスキームです:

( AA'がそれぞれ秘密鍵と公開鍵を表すと仮定します。また、 enc(text、key)dec(cyphertext、key)が暗号化/復号化機能を表します)

    +------------------------+------------------------------+
    |         SERVER         |            CLIENT            |
    +------------------------+------------------------------+
(1) | t = randomToken()      |                              |
(2) | enc(t, A)           -------->  c                      |
(3) |                        |       A' = getKeyFromUser()  |
(4) | p                 <--------    p=dec(c, A')           |
(5) | if (t==p)              |                              |
    |     allowAccess()      |                              |
    | else                   |                              |
    |     denyAccess()       |                              |
    +------------------------+------------------------------+

これに見られる弱点の1つは、交換を聞いていたBAD GUYが、Aを持っていないのに、既知の暗号文/平文の組み合わせを持っていることです。これは、暗号クラスから覚えているBADIDEAです。塩漬けでこれをなんとか軽減できると思いますか?

だからここに私の[2]の質問があります:

  1. これは「良い」スキームですか?(この最初の交換に続くものが平文であるかどうかは気にしないことを忘れないでください-私はここで最初の身元を確認しようとしているだけです)
  2. 上記の「既知の平文/暗号文のペア」の弱点を回避するための最良の方法は何でしょうか?塩漬け?

ありがとう!


編集: すべての議論に感謝します!明確にするために:

  • 私は、サーバーが彼らの言うとおりの人物であることをクライアントに保証することについて心配していません。反対のみ(サーバーにクライアントが彼らの言うとおりの人物であることを保証する)
  • 私はMITM攻撃について知っています。このスキームは、それらから保護することを目的としたものではありません。
  • 私はこれに対する解決策がすでにたくさんあることを知っています。これは純粋に私にとっての学習演習です!私は車輪の再発明やより良いネズミ捕りを作ろうとはしていません。これはただの楽しみです!
  • このスキームに対する私の思考プロセスは次のとおりです。(公開キーと秘密キーを適切に使用していないことはわかっていますが、しばらくお待ちください)

    • ボブはアリスに近づき、「ねえ、私はボブです」と言います。

    • アリスは、「わかりました。ボブの「秘密鍵」を知っています。本当にボブの場合は、暗号化したばかりのこの秘密メッセージ(ボブの秘密鍵を使用)を取得して、復号化してください。」

    • ボブは正しいメッセージで返信し、アリスは幸せです。

4

6 に答える 6

3

HTTPダイジェスト認証を使用できます。これは、ほとんどのブラウザ、サーバー、およびさまざまなライブラリですでにサポートされています。

編集:

SSL / TLSを使用せずに公開鍵暗号を本当に使用したい場合は、HTTPsecを参照してください。

本当に独自の認証スキームを発明したい場合は、ラベルの暗号化/復号化が間違っていることに注意する必要があります(タイプミスかどうか、または図を正しく読んでいない可能性があります。サーバー側でenc(t、A)を実行する):

  • 公開鍵を使用して暗号化します
  • 秘密鍵を使用して復号化します
  • 秘密鍵を使用して署名します
  • 公開鍵を使用して署名を検証します

あなたのスキームでは、サーバーが公開鍵を公開し、それを使用してクライアントに回答を暗号化させ、サーバーに送信する必要があります。サーバーは、秘密鍵を使用してそれを復号化できます。その場合の難しさは、公開鍵が実際に正規のサーバーのものであり、途中で攻撃者によって傍受されて置き換えられていないことを確認することです。そこで、PKIと証明書がTLS(およびHTTPS)で動作します。

于 2010-08-25T19:18:53.110 に答える
2

OAEPなどの適切なパディングメカニズムでRSAを使用する場合、既知平文​​攻撃に対して脆弱ではありません。したがって、それを回避する必要はありません。

見知らぬ人が立ち上がって、ボブであると主張します。それを証明するために、彼らは本物のボブだけが知っている秘密を知っていることを証明します。公開鍵暗号では、秘密は秘密です。

提案では、最初にボブの公開鍵を取得し、それが本当にボブのものであることを確認する必要があります。これにより、後でそれを使用して課題を暗号化できます。このプロセスをどのようにブートストラップしますか?

これで、「ボブ」はあなたのチャレンジに正しく応答し、彼のリクエストにいくつかの指示を付けます。真ん中の女性、イブがボブの本当の指示を切り落とし、彼女自身の指示に置き換えなかったことをどうやって知っていますか?

これは悪い計画であり、セキュリティを提供することに近づいていません。

これを追求する場合は、リクエストにデジタル署名する方法を検討する必要があります。たとえば、デジタル署名されたデータのチャンクをPOSTします。HTTPレベルの情報はすべて信頼できないものとして破棄され、デジタル署名されたメッセージのコンテンツのみが処理されます。

于 2010-08-25T20:27:32.720 に答える
1

この交換が始まる前にクライアントとサーバーが公開鍵を交換すると仮定すると、次のようなことができます。

  1. クライアントは、ユーザー名と暗号化(秘密鍵、ユーザー+ URL)の両方を含むヘッダーを使用してHTTP要求を送信します
  2. サーバーは、指定されたユーザーの公開鍵を使用してヘッダーの内容を復号化しようとします。
  3. 復号化が失敗した場合、または含まれているユーザーまたはURLが一致しない場合、要求は拒否されます。

URLは、別のリソースに対するリプレイ攻撃を防ぐために含まれています。暗号化されたデータにタイムスタンプを含めることで、リプレイに対するセキュリティを強化できます。

高品質の暗号化スキームを使用する場合、既知の平文攻撃は大きな問題ではありません。

編集:AES128の言及を削除しました。

于 2010-08-25T19:29:46.857 に答える
1

基本的に、HTTPにSSLを実装する必要があります。これはある程度実現可能ですが、本物ほど良くなることはありません。

暗号化されたデータを送受信できることは、問題の半分にすぎません。問題のもう1つの部分は、実際にサーバーと通信していることを確認することです(中間者攻撃について考えてみてください)。

SSLがどのように機能するかはよくわかりませんが、それが方法です。あなたはそれを読むべきです。しかし、あなたの計画の見た目からは、それはまったく無意味に思えます。なぜプレーンテキストをサーバーに送り返すのですか?これは、この設定を行う目的を無効にします。

これを行う方法は次のとおりです。

  1. サーバーはランダムトークンをクライアントに送信します。サーバーはトークンを「保留中」のリストに保存します。これらは一定の間隔でパージできます(例:15分ごと)
  2. クライアントenc(comb(username, password, token), pubKey)はサーバーに送り返します。サーバーにcomb()は、ユーザー名、パスワード、およびランダムトークンを組み合わせた関数があります。
  3. サーバーは、の逆数を使用decomb(dec(message, privKey))してユーザー名とパスワードを取得します。decomb()comb()
  4. サーバーは、トークンが保留リストに存在するかどうかを確認します。そうでない場合は、ログインの試行を拒否します。そうである場合、サーバーは通常どおり認証の実行に進むことができます。

生成されたトークンが繰り返されない場合、攻撃者は同じ暗号化されたメッセージを再送信することも、メッセージを復号化してすべてが何であるかを調べることもできません。

于 2010-08-25T19:23:46.587 に答える
0

ブルーノが言ったように、あなたが説明することは、かなり安全なHTTPダイジェストの線に沿っています。しかし、それを読んでみると、抜け穴があります。大きくない。誰かが実際にハンドシェイクでキーを取得するのを待って侵入できるようにする必要があります。セキュリティが問題である場合は、httpsを使用してそれに道を譲る必要があります。それがそこにある理由です。httpsには、最初に盗聴者に対してハンドシェイクを耐性にするための証明書があります。

于 2010-08-25T19:31:43.717 に答える
0

まず第一に、HTTPSは単なる暗号化以上のことを行います。また、アクティブなMTIM攻撃を防ぎ、セッションIDを保護します。セッションIDをこぼしただけでは、パスワードは無意味です。これはOWASPA9の一部です。

ただし、誰かがJavaScriptソリューションを実装しています。これは、セッションIDとパスワードの両方を暗号化します。これは、SSLと同様のDiffie-Hellman鍵交換を使用します。作者でさえ、httpsの代わりにはなりませんが、何もないよりはましだと言っています。https以外のものを使うことすら考えません。

于 2010-08-25T19:48:11.783 に答える