ブラウザのJavaScript暗号化を批判しているインターネット上の多くの記事があります:
公平な指摘もいくつかありますが、2017年の視点で分析し、ご意見を伺いたいと思います。そのために、暗号化されたノートサイトの考えられるアーキテクチャを定義して、セキュリティの側面に関する考えられる問題と解決策を提起できるようにします。
もちろん、SSLを使用します。
ユーザーがメモアプリに初めてログインしたときに、公開鍵を送信します。このキーは、crypto.js
スクリプトの信頼性を検証するために使用されます。公開鍵はユーザーのブラウザに保存されます。
checker.js
スクリプトもダウンロードされ、保存されます。このスクリプトは決して変更されず、crypto.js
および(2)の整合性のチェックを担当します。
(2)と(3)では、ユーザーと当社のサイトの間にTrust On First Use(TOFU)関係を確立します。公開鍵とchecker.js
の両方は、Service Workerなどを使用してキャッシュされます。 [〜#〜] sri [〜#〜] も使用して、整合性を最大化しようとします。
SSLを使用している場合でも、(2)および(3)のダウンロード中にMITM攻撃が発生する可能性があるため、公開鍵とchecker.js
が侵害されていないことを確認する方法を提供できます。たとえば、(2)と(3)のローカルコピーのハッシュを、私たちのサイトまたはサードパーティのサイトの実際のハッシュと比較します。このソリューションは完璧ではなく、これはおそらく弱いリンクですが、デスクトップアプリでも同様の攻撃が行われる可能性があると思います。
最初のログイン時に、ユーザーに秘密鍵も送信します。この秘密鍵は、メモの暗号化と署名に使用されます。この秘密鍵は暗号化されます。
復号化に必要なキー(6)は、電子メールでユーザーに送信されます。このようにして、2チャネル認証を確立します。
Web Crypto を使用して、(6)を(7)で復号化します。このようにして(6)は復号化されたブラウザに保存されることはなく、Web Crypto APIのおかげでJavaScriptからアクセスすることもできません。
これで、Webアプリの機能から始めることができます:暗号化されたメモを作成します。これを行うには、ユーザーはメモを書き、保存ボタンをクリックします。サーバーは、サーバーの秘密鍵で署名されたcrypto.js
を送信します(2を参照)。
署名は、(2)でダウンロードした公開鍵と(3)を使用して検証され、正しい場合、メモは暗号化されます。 checker.js
が変更された場合、SRIはこのプロセスを停止する必要があります。
メモはサーバーに送り返され、保存されます。
必要な機能に応じて、サーバーはユーザーの秘密鍵を削除し、公開鍵のみを保持するかどうかを決めます。
このセットアップについてどう思いますか?
(5)については不満ですが、これはネイティブソフトウェアで発生する可能性のある問題です。 インストーラーが侵害された を目にするのはこれが初めてではありません。また、インストーラーのダウンロード中にMITMが発生する可能性があります。そして、ネイティブコード署名は 完全ではない です。
Webクリプトは依然としてネイティブクリプトよりも厳密に悪いと思いますか?
ブラウザの暗号化を改善できる提案はありますか?
Webページの暗号化の主な問題は、実行しているコードがWebサーバーから読み込まれるため、サーバーはそのコードを完全に制御でき、ページを更新するたびにコードを変更できることです。そのサイトに新しいページを読み込むたびに(できれば、そのコードが実際に実行される前に)実行中のコードを手動で検査しない限り、そのコードが実際に何を行うかを知る方法はありません。
Web暗号化APIは、ページで実行されているスクリプトがアクセスできないように暗号化キーを安全に格納することにより、このリスクをある程度軽減できますが、これらのキーで実行できるすべての操作(復号化、署名など)は引き続き可能です。これらの(悪意のある可能性のある)スクリプトで使用できます。
あなたがdoを信頼している限り、ブラウザで悪意を持って動作しないようにサーバーを信頼することは非常に便利ですが、暗号化が使用される多くのアプリケーションでは、制御できないリモートサーバーでの信頼のレベルは受け入れられません。 。
特にあなたの計画のために:
- もちろん、SSLを使用します
これはいい。 SSLがなければ、攻撃者がコードを自分のものに置き換えるだけで、ユーザーのデータを好きなように実行できるため、その後のセキュリティ対策はすべて無意味になります。
- ユーザーがメモアプリに初めてログインしたときに、公開鍵を送信します。このキーは、「crypto.js」スクリプトの信頼性を検証するために使用されます。公開鍵はユーザーのブラウザに保存されます。
これは無意味なようです。 TLS alreadyクライアントにサーバーの公開鍵を送信し、それを使用して、その接続でロードするallスクリプトの信頼性を検証します。 JavaScriptで同じことを何度も行う理由はありません。
- 「checker.js」スクリプトもダウンロードされ、保存されます。このスクリプトは決して変更されず、「crypto.js」と(2)の整合性のチェックを担当します。
「このスクリプトは変更されない」という要件を強制する方法がないため、これも無意味です。 max-ageが長いCache-Controlヘッダーを送信することもできますが、ユーザーエージェントが常にその値を尊重する保証はありません。キャッシングはセキュリティのために依存することを意図していません。
- (2)と(3)では、ユーザーと当社のサイトの間にTrust On First Use(TOFU)関係を確立します。公開鍵と「checker.js」はどちらも、Service Workerなどを使用してキャッシュされます。
明確にする必要があります。ServiceWorkerでこれらのファイルをキャッシュしても、システム全体のセキュリティには影響しません。ユーザーが後でサイトに戻ると、ブラウザーはサーバーに問い合わせて、Service Workerが更新されているかどうかを確認し、更新されている場合は新しいバージョンをインストールします。したがって、サーバーはユーザーのブラウザで実行されているコードを完全に制御できます。ここには「Trust On First Use(TOFU)関係」はありません。
- SSLを使用している場合でも、(2)と(3)のダウンロード中にMITM攻撃が発生する可能性があるため、公開鍵と「checker.js」が侵害されていないことを確認する方法を提供できます。
これはいいジェスチャーですが、前述のように、これらのファイルが現在侵害されていない場合でも、サーバーまたはMITM(TLS接続をなんとかしてなんとかして管理した)はいつでも簡単にファイルを更新して、ユーザーに気付かれずに侵害することができます。そのため、この機能の要点はよくわかりません。
最初のログイン時に、ユーザーに秘密鍵も送信します。この秘密鍵は、メモの暗号化と署名に使用されます。この秘密鍵は暗号化されます。
復号化に必要なキー(6)は、電子メールでユーザーに送信されます。このようにして、2チャネル認証を確立します。
Web暗号( https://www.w3.org/TR/WebCryptoAPI/ )を使用して、(6)を(7)で復号化します。このようにして(6)は復号化されたブラウザに保存されることはなく、Web Crypto APIのおかげでJavaScriptからアクセスすることもできません。
これを実装するには、サーバーがユーザーの秘密キーのプレーンテキストバージョンにアクセスできる必要があります。これらのキーの使用目的によっては、サーバーが侵害された場合に問題が発生する可能性があります。代わりに、Web Crypto APIを使用してユーザーのデバイスで秘密鍵と公開鍵のペアを生成し、ブラウザーにその鍵の公開部分をサーバーに送信させることを検討する必要があります。これにより、サーバーはユーザーの秘密鍵にアクセスできなくなります。
これで、Webアプリの機能から始めることができます:暗号化されたメモを作成します。これを行うには、ユーザーはメモを書き、保存ボタンをクリックします。サーバーは、サーバーの秘密鍵で署名された「crypto.js」を送信します(2を参照)。
署名は、(2)でダウンロードした公開鍵と(3)を使用して検証され、正しい場合、メモは暗号化されます。 「checker.js」が変更された場合、SRIはこのプロセスを停止する必要があります。
信頼できないサードパーティのサーバーからchecker.js
をロードしているのでない限り、このシナリオではサブリソースの整合性は不要です。サーバーまたはクライアントへの接続を危険にさらしてchecker.js
を変更できるユーザーは、サブリソースの整合性ハッシュの値を変更して、ブラウザが変更されたスクリプトを問題なく受け入れるようにすることもできます。または、ページを変更してchecker.js
をまったく読み込まないようにし、代わりに独自の完全に異なるスクリプトを使用することもできます。どちらにしても、サブリソースの整合性は役に立ちません。
- メモはサーバーに送り返され、保存されます。
私がすでに6、7、8で述べた問題を修正して、サーバーがユーザーのファイルを復号化するために必要なキーを持っていない限り、それは問題ありません。サーバーがユーザーのファイルにアクセスするためのキーを持っている場合は、クライアント側の暗号化はまったく必要ありません。サーバーに暗号化を処理させるだけです。
- 必要な機能に応じて、サーバーはユーザーの秘密鍵を削除し、公開鍵のみを保持するかどうかを決めます。
または、私が示唆したように、最初からサーバーにユーザーのキーを与えないでください。それ以外は、ユーザーがサイトを使用していないときにサーバーがユーザーのファイルにアクセスできないようにするという点で、この部分はセキュリティ面で優れています。
ただし、ユーザーがサイトにアクセスすると、ユーザーのブラウザはそのサーバーからコードをロードし、ユーザーのキーを使用してユーザーのメモを復号化することができます。したがって、平均的なユーザーにとって、サーバーにそれらを読む機能を与えずにノートにアクセスすることは不可能です。
この実装には、ユーザーが新しいブラウザから自分のアカウントにサインインできず、ノートに引き続きアクセスできないことを意味するため、いくつかのユーザビリティの問題もあります。より良い実装は、高い作業係数を持つPBKDF2(Web暗号化API経由で利用可能)のような鍵導出アルゴリズムを使用して、パスワードからユーザーの暗号鍵を導出することです。これにより、どのブラウザからでもノートにアクセスできるようになります。 (しかし、上記の私のコメントで述べたように、すべて同じセキュリティ上の欠点があります。)
私にとって本当に際立っているのは6と7です。これが、この説明について私の最も不満を感じさせるものです。
TOFUを設定する全体のポイントは、双方向の信頼があるということです。もちろん、最初の使用の信頼には独自の問題があり、発生する可能性は低いですが、ほとんどの場合、それらのケースの概要を説明できたと思います。
しかし、あなたは私に言っています、サイトは私のために秘密鍵を生成し、その鍵を暗号化して渡してから、秘密を復号化する方法を私に与えますメールでキー?基本的に、メールで復号化する方法を復号化する方法を私に送信します。
つまり、私がサービスを利用するとき、私は通常、平等な露出を探します。私は、ウェブサイトが私がすることのすべての単一障害点になりたくありません。また、ユーザー向けのメッセージを、ユーザーが生成した秘密キーへのsysadminアクセス権を持つすべてのユーザーが解読できる状況も作り出します。つまり、私はそれを信頼することはできません。
これは、非対称暗号の要点を完全に覆します。特に、自分の秘密鍵を作成してサーバーに送信するのは簡単なので、公開鍵は簡単です。技術的な傾向がないユーザーでも、クライアントに含めることができます。 IMOまたはそのキーがeverインターネットに触れるために、他の当事者が秘密キーを作成する理由は絶対にありません。
他の点については他の人に答えさせましょう。6と7が最も危険だと思います。 OPで既に言及したMITMを除外します。
私がクライアント側の暗号化を行う唯一のコンテキストは、サーバーがそれらを認識しないようにクライアントの資格情報(パスワード、クレジットカード情報など)をハッシュすることです。はい、サーバーは有効性をチェックするために必要なプレーンなパスワードを知る必要はありません。サーバーは受信したパスワード文字列に独自のハッシュを適用します。クライアントが同じハッシュを送信する限り、スキームは正常に機能します。サーバーがクライアントのプレーンパスワード/クライアントハッシュアルゴリズムにとらわれない間、有効なパスワードが認証されます。以前は、一部のクライアントがhttps/tlsにシステムを実装するという推奨事項に従わなかったときに、ユーザー名を暗号化/復号化していました。サーバーがユーザー名を知っている/保存しているため、SSL通信ではユーザー名の暗号化/復号化は無意味です。どういう意味?コンテキストによってサーバーがクライアントの秘密データにとらわれない限り、クライアント側の暗号化はお勧めしません。クライアントシークレットをサーバーから保護したり、サーバーを神聖な規模の脆弱性から保護したりするためです。他のすべてのコンテキストでは、主要道路(https、tlsなど)から逸脱しないでください。
追伸一部のユーザーは、レコード管理、ドキュメント管理のコンテキストに関して、パスワードにユーザー名の単語を使用するのが愚かです。私のお気に入りの攻撃は、ユーザー名へのタイミング攻撃であり、次に、パスワードへのタイミング攻撃が直接失敗した場合に、ユーザー名をパスワードに対する辞書攻撃の貴重なリソースとして使用します。ドキュメント/レコード管理ソフトウェア開発の世界では、ユーザー名へのタイミング攻撃に関心のある人はほとんどいないことがわかります。