2016-09-29 15 views
0

私は中央のWebサーバー(Node.js)を持っていて、複数のクライアントマシン(Nodeも稼働しています)を持っています。これらのクライアントはWebサーバーにデータをプッシュしようとしているので、セキュリティのためにクライアントは最初にメインサーバーに登録します。独自のSSL秘密/公開キーを生成し、サーバーに公開キーを格納します。Node.js:一意の公開鍵を使用してクライアントを認証します(Github SSH鍵認証に似ています)

登録後、クライアントがサーバとの通信を試みるたびに、自身を認証するために公開鍵(?)を提示する必要があります。

私はこれについてどうやって行くのか理解しようとしています。クライアントのすべての公開鍵の内容を通常のデータベースコレクションに格納する必要がありますか?

どのようにしてクライアントが実際に自分の証明書を自分のデータとともに「プレゼント」するのですか?私はclient-certificate-authのようないくつかのパッケージを見たことがありますが、これは私のユースケースのために役立つとは思わない。

EDIT:私はHTTPS(ポート443)を介して通信していますので、実際のセキュリティ部分を担当していると思います。私はちょうど不正な登録されていないクライアントがpub/private暗号化/ SSL証明書を使ってサーバにデータをプッシュしないようにしたい。

+0

微妙なWeb暗号APIを使用する予定ですか?私はあなたが欲しいものを理解していると思います。私はあなたのための例を書くことができます...あなたは、JavaScriptで生成された秘密鍵をクライアントで秘密にし、公開鍵をサーバに安全に送信して保存したい... – TylerY86

+0

認証時に、クライアントは公開鍵固有の識別子トークンによって識別される。次に、サーバーは、ユーザーの公開鍵で暗号化されたメッセージペイロードでチャレンジを発行します。ユーザーは自分の秘密鍵でメッセージを復号化し、正しく応答します。これは* no *セキュリティを提供します。すでに確立されているSSL接続でこれを実行する必要があります。伝統的なクッキーとセッショントークンの代わりに使用されています。秘密鍵は決して​​サーバに到着しません。 – TylerY86

答えて

1

このパスを終了する場合は、Subtle Crypto APIを使用してください。おそらく、あなたはこれをしてはいけません。

JavaScriptで生成された秘密鍵をクライアントで秘密にし、公開鍵をサーバーに安全に送信して保存したいとします。認証中

、はそれが公開鍵何と言うクライアントは、例えば、それは公開鍵だと関連するいくつかのユニークな識別子でありますidまたは共通名またはユーザー名。

サーバは、クライアントの公開鍵で暗号化されたメッセージペイロードでチャレンジを発行します。

ユーザーは、秘密鍵でメッセージを復号化し、正しい復号化応答で応答します。

これはセキュリティを提供しません。すでに確立されているSSL接続でこれを実行する必要があります。

伝統的なクッキーとセッショントークンに代わるものであり、それはただ違っていて、難しく、良くないです。

秘密鍵は、いつでもサーバーに到着することはありません。クライアントは秘密鍵を使用して暗号化しません。公開鍵暗号化の仕組みではありません。

しかし、デジタル署名を送信することができ、サーバーはそれを確認できます。それは一意の識別子の代わりです。あなたが本当にサインするのに十分な長いナンスを指定していることを確認してください。

デジタル署名チャレンジを実行するには、サーバーがクライアントにチャレンジ文字列を送信し、クライアントはそれが秘密鍵だとサーバーに応答使って挑戦に署名し、その後、サーバーは公開鍵を使って署名を検証公開鍵は署名の一部でなければならず、サーバは公開鍵を信頼する必要があることを知っている必要があります。そのため、迅速に検索する方法が必要です。

また、独自のクライアント証明書を設定する際にユーザーの知識に頼ることもできます。この場合、Paulの答えに記載されているpassport-client-certが対応できます。

1

私はこれを自分でしないことを強くお勧めします。正しく実装していないと間違ってしまうことがたくさんあります。

しかし、この種の仕組みは構造的にはではありません。 "クライアントの公開鍵を提示"する代わりにクライアントが秘密鍵で何かを暗号化し、その暗号化されたデータをサーバーに送りますクライアントの公開鍵で復号化します。それができれば、クライアントはそれが主張しているクライアントであることがわかります(理論的には、この信頼性はキースペースによって異なります)。

クライアントは何を暗号化しますか?まあ、それはあなたが/パラノイドであることを望む(どれくらい)安全であるかに大きく依存します。これを行う1つの方法(準ケ​​ルベロス)は、クライアントが情報を暗号化するためにサーバーに要求を送信することです。これはSSLを介して行われるため、クライアントはサーバーが本人であることを保証することができます(CAなどを確認できます)。それは、ランダムな値、有効期限、おそらく何らかの種類のノンスを含むデータです。また、後で照合のためにサーバによって保存され、当然、時間の経過と共に退去する。クライアントは、通常、その正確なオブジェクト(おそらくJSONオブジェクト)を取り出し、それを秘密鍵で暗号化し、それをいくつかのログインエンドポイントにサーバーに返します。先に述べたように、サーバーはクライアントのIDに基づいてそのオブジェクトの格納場所を確認し、比較して2つのオブジェクトが同一かどうかを確認します。もしそうであれば、クライアントはそれが誰であるかを受け入れることができます。

通常、このハンドシェイクは、クライアントがすべてのトラフィックを暗号化するために使用できるセッションキーを交換するためにのみ行われます。対称キーの暗号化は通常、PKIよりもCPU上で簡単です。

正直言って、私は表面を傷つけただけです。あなたは、PassportJSが戦略のために提供しなければならないものを見て、その1つを選ぶ方がずっと良いでしょう。おそらくpassport-api-keyまたはpassport-client-certが必要な処理を行います。

+0

私はPKIチャレンジを後ろ向きにしていると思います...クライアントは私有鍵で暗号化しません。 – TylerY86

+0

デジタル署名の挑戦を考えているかもしれません。 – TylerY86

+0

この場合、技術的には署名と呼ばれますが、既知のバイトを暗号化するプロセスはまだあります。 – Paul

関連する問題