ユーザー認証のためのJavaScriptでのペイロード暗号化の安全な方法

Vue.js で記述されたフロントエンドアプリケーションを認証し、Discourse ユーザーの user_api_key を取得するログインフローを作成しました。これは @samこちらで書いているガイドラインに従っています。

認証は機能していますが、問題となっているのは秘密鍵を安全に保存することです。現在、秘密鍵は .env ファイルにローカルで保存され、ペイロードの暗号化/復号に使用されています。これはペイロードを暗号化する安全な方法でしょうか?もしそうでない場合、フロントエンドの JavaScript アプリケーション向けの代替案はありますか?

よろしくお願いいたします。

「いいね!」 5

Electron や Tauri のアプリの場合ですか?あなたが何を選ぶかはわかりませんが、おそらく安全な保存のための何らかの仕組みがあるでしょう。運が良ければ、Mac ではキーチェーン、Windows ではそれに似た機能を利用できるかもしれません。

「いいね!」 4

これはサーバー上でホストされている Web アプリケーションです。問題点は、秘密鍵が漏洩した場合、何らかの形でペイロードが傍受される可能性があることです。JavaScript 暗号化全般に共通する懸念であることは理解していますが、Discourse から Web アプリを認証する際により安全な手法があるかどうかを確認したいと考えています。

ユーザーの API キーシステムはこのユースケース向けに設計されていません。ユーザーのためにプライベートキーを生成し、それをサーバーに保存するという手間をかけるなら、なぜそのようなことをするのでしょうか。単にサーバー側でキーを生成すればよいのです。

実際の問題が何かをより詳細に理解していない限り、適切なガイダンスを提供するのは非常に困難です。Web アプリにプロキシエンドポイントを提供し、すべての認証をアプリ側で処理するのはどうでしょうか。

「いいね!」 4

@owengot と話し合った後、問題の詳細な説明を以下にまとめました。

これは Vue.js ベースの Web アプリケーションで、独自のサーバーサイドコンポーネントは持たず、スタンドアロンの Web アプリケーションとして Discourse API を利用しています。つまり、ある意味では Discourse 自体がサーバーとして機能しています。使用例としては、ユーザーアカウント名下の Discourse トピックにコンテンツを投稿するスタンドアロンのアンケートやフォームなどが挙げられます。このようなソフトウェアをカスタムのサーバーサイドコンポーネントなしに構築できるという点で、このアーキテクチャは魅力的でした。そのため、可能な限り「サーバーサイド」の処理は避けたいと考えています。

現在、User-API キーの取得は意図通り機能していますが、@owengot が JavaScript 上で秘密鍵を生成するステップに非常に時間がかかる(最大10秒かかるなど、JavaScript では非効率的である)ことを発見しました。その後、同じ秘密鍵を複数のユーザーで共有できるというハックを発見し、それを Web ホスト上のファイルに保存しました。このホストは Web アプリケーションの他の静的ファイル(JS、CSS など)も提供しています。これにより高速化されましたが、その秘密鍵は(1)共有されたものとなり、(2)公開 URL でアクセス可能な状態で保存されることになりました。これは、ええと、恐ろしいことのように思えます :fearful:

そこで、このハックのセキュリティ上の影響について Discourse チームに相談する必要があると伝えました。ここでは二つの基本的な選択肢があります。

  • もしその秘密鍵が「単に」ペイロードの暗号化にのみ使用されるのであれば、通信自体が SSL/HTTPS で暗号化されているため、この状況でも許容できるかもしれません。

  • しかし、その秘密鍵を知ることで、後に誰かの Discourse アカウント名下で投稿するために使用される User-API キーを計算できるのであれば、このハックは明らかに受け入れられません。

私もこれについて興味があります。@owengot が開発したソフトウェアを使い始めたからです。@tanius さんの意見では、これは安全な方法だと思いますか、@sam さん?

はい、これはやめておきましょう。秘密鍵はクライアントごとに秘密に保つことを意図しています。

鍵生成に 10 秒かかるのは、あなたが支払う必要があるコストです。これを高速化するいくつかの JS 暗号 API も存在します。

「いいね!」 3