web-dev-qa-db-ja.com

暗号化-RSAまたはAESを使用する必要がありますか?

私のモデルは、他のクライアントの一部(すべてではない)と話したいクライアントが複数いるモデルです。

すべてのメッセージはサーバーを介して送信されます。

相互に通信している2つのクライアントのみがメッセージを認識できます。したがって、サーバーと他のクライアントは、どのメッセージが送信されたかを把握できないはずです。

2つのクライアント間の通信は、1日に数回開始および終了します。

メッセージは長さが無制限の可能性があるプレーンテキストになりますが、はるかに短くなる可能性があります。SMSスタイルのメッセージと考えてください。

このような状況で、メッセージを暗号化するにはどうすればよいですか?速度や効率の向上につながる追加コードを書いてもかまいません。

RSAとAESの動作の大まかな基本は知っていますが、何が最適かわかりません。

RSAの公開鍵と秘密鍵のペアを生成するときに、新しいペアを生成する必要がある状況はありますか?または、1つのクライアントが1つの公開鍵を持ち、彼と話をしたいすべての人に同じ鍵を与えて、彼だけがメッセージを読むことができるが、彼らは将来のすべてのメッセージの公開鍵を保存することができますか?

または、クライアントのペア用に個別の対称AESキーを用意し、コンタクトが最初に開始されたときにそれを共有して、それを永久に使用する必要があります。繰り返しますが、これを再度生成する必要がある状況はありますか?

クライアントがクラッシュ/シャットダウン/リブートした場合に保持されるように、キーをどのように保存しますか?

39
Cheetah

どちらでもない限り、どちらでもありません。 間違った質問をしている 。この段階では、暗号アルゴリズムについて考えるのではなく、暗号プロトコルについて考える必要があります。

暗号化プロトコルは設計が難しく、セキュリティバグが頻繁に発生します。公開鍵暗号を完全に理解していないため、独自の暗号プロトコルで使用する準備ができていません。

高レベルでは、モデルは公開鍵暗号化(RSAなど)に適しています。すべてのクライアントに独自の秘密鍵を持たせ、その公開鍵を他のクライアントに公開します。クライアントの秘密鍵は、クライアントが侵害されない限り、時間の経過とともに変化しません。対称暗号(AESなど)は、クライアントの各ペアが独自の秘密鍵を持つ必要があるため、ここではうまく拡張できません。

可能な限り既存のソフトウェアを使用してください。暗号化プロトコルの実装は、それらを設計するのとほとんど同じくらい難しいものです。クライアントがときどきメッセージをメール形式で相互に送信するモデルの場合、うまく機能するツールは GnuPG です。 (双方向通信の場合、 SSL/TLS を使用します。)

つまり、日常の操作でメッセージを送信するには、gpgを呼び出し、受信者の公開鍵で暗号化します。その間に、送信者の秘密鍵で署名します。メッセージを受信したら、送信者の公開鍵と照らし合わせて署名を確認し、受信者の秘密鍵で復号化します。つまり、gpg --sign --encrypt -r NAME_OF_RECIPIENTgpg --verify に続く gpg --decrypt

残りの問題は鍵の配布の問題です。クライアントは、キーペアを生成した後、攻撃者が送信中に公開キーを傍受および交換することを許可せずに、それについて他のクライアントに通知して配布する必要があります。これを行う方法は、正確なシナリオの多くに依存します。この部分のセキュリティを無視しないでください。

GnuPGの呼び出しが遅すぎることが判明した場合にのみ、軽量の、おそらく自家製の類似プロトコルの使用を検討してください(電子メール範囲のオーバーヘッドからSMS範囲のオーバーヘッド)公開鍵の暗号化は大きなメッセージに対して高価であるため、GnuPGは内部で各メッセージの対称鍵を生成します。公開鍵アルゴリズムは、対称鍵の暗号化とファイルのダイジェストへの署名にのみ使用されます。対称暗号化にAESを使用し、ダイジェストアルゴリズムとしてSHA-256を使用し、公開鍵アルゴリズムとしてRSAを使用することをお勧めします。

インシリコですでに述べたように、RSAとAESは2つの異なる目的を果たします。 AESは、会話全体の暗号化に適した高速アルゴリズムです。しかし、問題があります。他の当事者がそれを知らずに2つの当事者間で使用する鍵を決定する方法は?

RSAはこれに対する解決策となり得ます。すべての参加者が他のすべての参加者のRSA公開鍵を持っている場合、誰でも(他の参加者の公開鍵を使用して)誰とでも暗号化通信を開始し、使用する秘密AES鍵を決定できます。 AESキーが決定したら、残りの会話はAESを使用して暗号化できます。参加者Bが本当はAであることを証明するには、デジタル署名を使用できます。

私が説明したのは、ブラウザがSSL対応のWebサーバーに接続したときにSSLハンドシェイクが行う動作です。

19
JB Nizet

これを間違った方法で行わないでください...

RSAとAESの動作の大まかな基本は知っていますが、何が最適かわかりません。

あなただけの基本を知っているなら、あなたは正しい人ではないかもしれません(まだ)この問題を解決します。セキュリティは、very細心の注意を払わなければならない分野の1つです。そうしないと、セキュリティ設定全体が無効になります。

さらに、私はあなたに適切な答えを与えるのに十分な情報があるとは思いません。セキュリティの期待に関するビジネス契約は、事前に知っておく必要があります。

ほとんどの場合、セキュリティ上の理由から、鍵は生成されたマシンから離れることはありません。したがって、情報を「共有」する場合は、通常、純粋なセキュリティの観点から公開鍵ソリューションが適切です。これの例外は、物理メディア上の人にキーを送信するなど、安全な方法で対称キーを共有できる場合です。

6
Andrew White

基本的に、公開鍵暗号化(RSAなど)を使用すると、対称鍵暗号化(AESなど)を使用するよりもはるかにコストがかかります。また、互いに転送するメッセージが多い場合は、対称鍵暗号化を使用することをお勧めします。キー。

現在、対称鍵の作成と交換は、公開鍵暗号化を使用して行うことができます。

例えば:

各クライアントには秘密鍵と公開鍵のペアがあり、公開鍵はサーバーに格納されています。 2つのクライアントが通信セッションを開始すると、それぞれがサーバーから他方の公開鍵を取得し、暗号化された番号を他方に送信します。次に、それぞれの側でこれら2つの数値をハッシュし、その結果をキーとして使用して、今後データを暗号化/復号化します。

3
MByD

PUBLIC/PRIVATEスタイル(十分なビット数のRSA :))を使用する場合は、次のように、安全な通信の種類を設定できます。

  1. アリスがメッセージを書く
  2. アリスはAlice[〜#〜] private [〜#〜]キーを使用して暗号化します
  3. アリスはBob[〜#〜] public [〜#〜]キーを使用して再度暗号化します
  4. アリスは結果をボブに送信します。

次に:

  1. ボブはアリスから(おそらく)メッセージを受け取ります
  2. ボブはBob[〜#〜] private [〜#〜]キーを使用して復号化します
  3. ボブはAlice[〜#〜] public [〜#〜]キーを使用して再度復号化します
  4. すべてがうまくいけば、ボブはメッセージを読みます。

注意:

  • このメッセージを読むことができるのはボブだけです。
  • ボブはそれがアリスから来たことを間違いなく知っています。

AESでこれらの属性を両方とも取得するのは少し難しいです。

2
Jesse Chisholm