web-dev-qa-db-ja.com

Keygen要素を使用して相互認証TLSの証明書を作成する必要がありますか?どのような選択肢がありますか?

相互認証TLSを使用して javascript based webservices のセキュリティを向上させることに興味があります。 Keygen要素と すべての問題を考慮して を調べましたが、これがこの目的に使用できるかどうかはわかりません。

相互認証TLSが(簡単に言えば)TLSのより安全な形式の1つであると私が考えるのであれば、この目的のためにKeygenから送信された暗号化資料を使用するのは理にかなっているでしょうか。


更新:

私の脅威モデルはDiginotarスタイルの攻撃から保護することです。ソリューションは次のようになります。

登録

  1. ユーザーがWebサイトにログオンするか、アカウントを作成します。
  2. 永続的なCookieを追加する代わりに、マシンがこれまでに見られたことがない場合(新しいアカウント)、クライアント側の証明書を作成するように求められます。
  3. クライアント側の証明書はサーバーによって署名され、クライアント認証のためにWebブラウザーにインポートされます
  4. サーバーはクライアント証明書の詳細(拇印/ハッシュ/公開鍵)を登録し、後でセッション検証に使用します。

認証

  1. ユーザーがWebサイトにログオンする(n + 1訪問)
  2. ユーザーはクライアント証明書の入力を求められます
  3. サーバーはクライアント証明書を検証します。
  4. 相互TLSが確立されます。
  5. サーバーは認証された呼び出しを既知のクライアント証明書で検証します。呼び出し証明書が空白または別のユーザーからのものである場合、MITMが実行されている可能性があり、アクセスが拒否されます。
5

Keygen要素の使用には多くの欠点があると思います。keygen要素は既に投稿で列挙されています。簡単にアクセスでき、多くのクライアントと互換性のあるWebサービスがある場合、keygenを使用してクライアント側の認証を実装することは非常に困難です。

最良の解決策は、CAによって署名されたプリロードされた証明書を使用して、暗号化トークンをクライアントに提供することです。もちろん、クライアント証明書の生成と配布を管理する必要があるため、多くのクライアントがあり、CAのインフラストラクチャがない場合、これは非常に複雑になる可能性があります。このソリューションの利点は、クライアントにとって非常に強力な認証メカニズムになることです。

MITM攻撃を防止するだけの場合は、ほとんどの場合、SSLと適切なユーザー/パスワードアクセスメカニズムを使用するだけで十分です。

それはあなたが持っているリソース、あなたが何を保護しようとしているのか、そして誰からそして誰があなたのアプリケーションのユーザーであるかに大きく依存します。安全なシステムを構築するプロセスの最初のステップは、この質問に答えることです。


更新:

あなたが説明した脅威モデルに関して、あなたのモデルが侵害されたCAに対する保護を提供するとは思いません。次に例を示します。

  • CAが侵害され、ドメインの証明書が発行されます
  • クライアントのDNSが危険にさらされているため、ドメインを照会すると攻撃者のIPで応答します
  • クライアントは接続を試み、悪意のあるサーバーとの接続を確立し、それがサーバーに接続します。
  • 不正サーバーは、新しいデバイスから接続するクライアントとして機能し、新しいクライアント証明書が生成されます。
  • 実際のクライアントが既存の証明書を送信しても、不正なサーバーはそれを無視します。

上記の攻撃では、クライアントが複数の証明書(接続元のデバイスごとに1つ)を持つことができると想定しています。この動作を実装したくない場合、通常のクライアントが証明書を自分が使用しているすべてのデバイスにコピーするのは非常に困難です。もちろん、ユーザーエクスペリエンスも低下します。

全体として、侵害されたCAからの保護は厳しいビジネスであり、DNSECのような新しいテクノロジーが大規模に実装されていない限り、できることは多くないと思います。

一方、有名なCAのハッキングは、毎日発生するものではありません。 noname CAから証明書を購入しないようにしてください。現時点では十分なセキュリティが確保されているはずです。

2
Dinu

SSLを使用した証明書ベースのクライアント認証を行うには、クライアントが証明書を「所有」する必要があります。つまり、秘密鍵および対応する証明書(サーバーが発行したCAが発行)にアクセスできる必要があります。受け入れます)。クライアントがWebブラウザーの場合、それをエスケープする方法はありません。ブラウザーはキー自体を知っている必要があります。

ブラウザが秘密鍵と証明書のペアを「知る」には、2つの方法があります。

  1. CAにキーペアを生成させ、証明書を作成させ、全体をPKCS#12/PFXファイルとしてパッケージ化してから、ブラウザにインポートします。
  2. ブラウザにキーペアを生成させ、証明書を生成するCAに公開キーを送信します。次に、証明書がブラウザにインポートされます。

2番目の方法は、一般的に「より良い」と見なされることがよくあります。特に、証明書を法的に拘束力のある方法で後で文書に署名するために使用する必要がある場合、鍵のライフサイクルの詳細が法的価値にとって重要です。詳細は複雑で、現地の法律に大きく依存しますが、大まかにまとめると、たとえユーザーのコンピューター以外のシステムに一時的な方法であっても秘​​密鍵が存在すると、機能しなくなります。ただし、authenticationシナリオでは、特にSSL/TLSセッションの場合、これは問題にならない可能性があります。

<keygen>要素は、2番目のモデルを実装するHTML5の方法です。これは実際にはHTML5よりもかなり古く、そのルーツはNetscape Navigatorにあります。使用方法の詳細については、 this page および that file を参照してください。 Internet Explorerの場合は、Xenrollと呼ばれていたMicrosoft固有の方法を使用する必要がありますが、CertEnrollのために廃止されました(概要については、 このブログの投稿 を参照)。 Microsoftは<keygen>の実装に消極的であることが証明されています。これは、 彼らは が好きではないためです。

とにかく、SSLレベルの証明書認証を行う場合は、ユーザーインターフェイスの種類と競合し、ブラウザーがサポートするものを体験する必要があります。これは、人間工学的に完全に最適ではありません。代替手段には、認証の実行 SSLトンネルが含まれます。これは、Webコンテキストでは、ユーザーが入力するもの(パスワードまたは同等のクリックオマティック)またはJavaScriptトリックのいずれかを意味します。 JavaScriptの問題は、一部の non-standard features が使用されない限り、秘密鍵(およびスマートカードへのインターフェース)のクライアントOSリポジトリにアクセスできないことです。

SSL/TLSでの証明書ベースの認証は、 必ずしもそうとは限りません 他の認証方法より「安全」です。証明書を使用すると、ID認証から分離できます。これは素晴らしい機能ですが、アーキテクチャ全体がそのような分離を要求しないシステムでは役に立ちません。

2
Thomas Pornin