web-dev-qa-db-ja.com

安全な方法でWebベースの認証にGPGまたはSSHキーを使用することは可能ですか?

仮に、GPGキーまたはSSHキーの生成と使用に問題のない、技術志向のセキュリティ意識の高いユーザーを対象としたWebアプリケーションを書いているとします。

上記のキーを使用して、安全な方法でWebアプリケーションで認証し、従来のパスワードベースの認証を置き換えることはできますか?

可能であれば、認証手順はどのようになりますか? Ruby、.NET、JavaまたはPythonなどの一般的な言語およびプラットフォーム用に、そのようなアイデアの既知の優れた実装があるでしょうか?

それが不可能な場合、その理由は何ですか? GPGキーチェーンまたはSSHキーファイルにアクセスするWebブラウザーに制約があるのでしょうか?

36
user10211

Webアプリケーションの場合、主な問題は、Webサイトのコード(ブラウザーのJavaScript)がファイルを自由に読み書きできないことです。まあ、一般的に、これは問題の恩恵ですが、ここでは、JavascriptコードがSSHまたはPGP秘密鍵にアクセスできないことを意味します。

ユーザーがどれだけテクノロジーに精通しているか、およびユーザーが許容する手動操作の数に応じて、実行できることがいくつかあります。

  • Webサイトに代わってSSHまたはPGP秘密鍵にアクセスするローカルにインストールされたブラウザー拡張機能を使用できます。できれば、いくつかのユーザーコントロールをお勧めします。Webサイトが署名したからといって、署名を行うブラウザーは必要ありません。

  • サーバーはSSHサーバーとして機能する場合があり、SSHおよびキーベースのクライアント認証を使用してクライアントに接続する必要があります。ユーザーは「SOCKSプロキシ」モードでSSHを実行します。 Webサーバー自体はlocalhostのみをリッスンします。つまり、このようなローカルプロキシを経由しない限り到達できません。このモードでは、WebサーバーはHTTPSではなくHTTPであってもかまいません。これは本当にSSLをSSHに置き換えることになります。サーバー側では、ユーザーを追跡するために mod_ident または類似のものを使用する必要があります(SSHサーバーはクライアントが誰であるかを認識していますが、情報はHTTPサーバーに転送する必要があります。幸い、これは同じですマシンなので、UnixレベルのIDを使用できます)。

  • Webサイトは、ランダムなコンテンツを含むダウンロード可能なファイルとして「チャレンジ」を表示する可能性があります。ユーザーはファイルを取得し、GnuPGで署名し、(ASCIIでアーマードされた)出力をWebサイトのテキストフィールドに貼り付けます。サーバーは署名を検証し、ユーザーの認証としてそれを受け入れます(サーバーがユーザーの公開鍵をすでに知っている場合)。不格好ですが、機能します。

PGP実装は電子メールソフトウェアに埋め込まれていることが多く、また外部ルートCAを信頼する必要がない可能性があるため、上記のメールベースのバリアントが推奨されます。次のようになります。

  • ユーザーはHTTPSを使用してWebサーバーに接続します。サーバーは自己署名証明書を使用します。ブラウザーはそれについて警告しますが(「赤い恐ろしい警告」)、ユーザーは続行できます。

  • サイトでは、ユーザーは自分の名前を入力します。次に、サーバーは署名および暗号化された電子メール(PGPを使用)をユーザーに送信します。署名された電子メールには、ランダムなナンスと、サーバーのSSL証明書のサムプリントのコピーが含まれています。ランダムなナンスもWebサイト自体に印刷されます。

  • ユーザーはサーバーの電子メールでPGP署名を確認し、サムプリントがブラウザーから確認できるものと一致することを確認します。これにより、正規のサーバー証明書が表示されていることをユーザーに確信させることができるため、進行中の 中間者攻撃 は発生しません。 (ここで、X.509 CAシステムをPGPベースの検証に置き換えます。)

  • ユーザーは、Webサイトに表示されたナンスが、電子メールで表示されたナンスと一致することも確認します(これは重要です)。

  • ユーザーはその内容を送り返すことによって電子メールに応答します。今回は自分のPGP秘密鍵で署名し、サーバーの公開鍵で暗号化します。サーバーはその電子メールを検証し、したがってnonce値が実際に意図したユーザーによって受信されたことを認識します。

  • サーバーはnonce値をcookieとしてユーザーのブラウザーに送信します。これにより、ユーザーをさらに認証ラウンドに煩わせることなくブラウジングできます。 Cookieを有効な認証トークンとして受け入れる期間を決定するのはサーバーです。

上記のスキームでは、電子メールの応答を返信することにより、ユーザーはサーバーに実際にnonce(電子メールに含まれている)を返す人が本人であると想定することを承認していることに注意することが重要です。このため、ナンスがWebページに表示されているものと一致することを手動で確認することが重要です。

17
Thomas Pornin

OpenPGP/SSHキーペアを使用して、安全な方法でWebアプリケーションで認証し、従来のパスワードベースの認証を置き換えることは可能ですか?

はい。それはかなり可能です。

可能な場合、認証手順はどのようになりますか? Ruby、.NET、JavaまたはPythonなど)のような一般的な言語やプラットフォームで、このようなアイデアの既知の優れた実装はおそらくありますか?

次の質問については私の回答を参照してください。

それが不可能な場合、その理由は何ですか? GPGキーチェーンまたはSSHキーファイルにアクセスするWebブラウザーに制約があるのでしょうか?

WebアプリでのSSHおよびOpenPGPキーの処理は、サードパーティのライブラリ(特にCまたはJavaライブラリが豊富なエコロジーを前提としている)を使用することで可能ですが、最も一般的な既存のソリューションを活用できません- SSL/TLS。

最善の策は、ユーザーがサーバーによって署名されたX509クライアント証明書を生成して自分自身を認証することです。これにより、WebアプリはWebコンテナー(Catalina Tomcat、ApacheD、IISなど)に依存して、シームレスな暗号化と認証を実行できます。応用。

内部では、OpenPGP鍵はX509証明書と同じRSA指数を持っているため、opensslなどのツールはGPG/PGP鍵を自己署名* X509証明書に変換できます。 SSHキー についても同様です。

* X509v3は、私が決定した限りでは、複数のルートを持つ信頼チェーンを持つことができないため、OpenPGP web-of-trustはX509の観点から「自己署名」と見なされます。

8
LateralFractal

既存の回答は良いアドバイスを提供します-代わりにブラウザーでSSLスタックを使用してください。

ただし、JavaScript暗号化を使用することで、希望どおりの操作を実際に行うことができます。

JavaScriptにはOpenPGP実装があります http://openpgpjs.org/ その品質を保証できません。

また、HTML5 JavaScriptがローカルファイルにアクセスすることも可能です。 http://www.html5rocks.com/en/tutorials/file/dndfiles/

これは実際のシステムよりも好奇心が強いと思います。

4
paj28