web-dev-qa-db-ja.com

このRSA / AESの組み合わせは良いですか?

私が参加している開発者チームは、サーバーとモバイルデバイスの間で機密データを交換する安全な方法を開発しようとしています。

次のアルゴリズムを考え出しました。

  1. デバイスは秘密RSAキーを生成し、公開キーをサーバーに送信します。

  2. サーバーはユーザー固有のAESキーを生成し、RSA公開キーを使用してそれを暗号化してデバイスに送り返します。

  3. デバイスはAESキーを取得します。これを使用してパスワードとユーザー名を暗号化し、サーバーに送信します。

  4. サーバーはユーザー名とパスワードを復号化します。一致する場合、AESキーは、X時間またはログアウトまでの安全な通信に使用されます。そうでない場合は、プロセスを再起動する必要があります。

安全ですか?それを改善できる方法はありますか?欠点は何ですか?

編集:コメントを読んだ後、より安全な代替案は何ですか?なぜですか?

Edit2: OK、わかりました。私は自分の実装を使用しません、すでに試みられて証明されたものを見つけます。

11
Adrian Sicaru

プロトコルのすべての弱点は、「SSLを使用する」または「SSLを使用する!」と要約することができます。

詳細:

  • すべてのプロトコルはもちろん偽装に対して脆弱です。具体的には 中間者攻撃 とも呼ばれる二重の偽装です。
  • 同様に、回線を盗聴できる潜在的な攻撃者のいずれかが転送中のデータのmodificationを行うことを決定した場合、攻撃者は可能であり、クライアントとサーバーは賢くなります。
  • 経験によれば、「すべてのデータをそのキーで暗号化する」と言ってから正しく実行するのは非常に複雑です。 SSL自体はそれを行うのにほぼ15年かかりました、そして、多くの実装はまだそれに応じていません。オラクルのパディング、予測可能なIV、MAC検証タイミング、検証済みのクロージャー、パケットのリシーケンスとリプレイに対する保護...

全体的な評価として:しないでください。

34
Thomas Pornin

いいえ、このプロトコルは安全ではありません。

コメントですでに述べたように:

独自の暗号をロールバックしないでください。間違っている可能性があります。特に、自分が何をしているのか本当にわからないと認めた場合。

まず、すでに標準プロトコルがあり、Niceプロパティとセキュリティ証明がある標準的な問題があるようです。データ転送のプロトコルは TLS v1.2 (またはそれ以降)である必要があります。ライブラリを使用する必要があります( [〜#〜] nss [〜#〜]GnuTLS または OpenSSL など)。パスワード認証の場合、最適な選択肢は [〜#〜] srp [〜#〜] または TLS-SRP を使用することです。ただし、SRP(これが最初の選択肢であるはずです)を買う余裕がない場合でも、 この論文 に従うことができます。
これまでのところ改善。

次に、プロトコルの欠陥について説明します。

  1. 中間者攻撃 に対して脆弱です。攻撃者がデバイスとサーバーの間に座っている場合、攻撃者は公開鍵を釣り、それを自分のものに置き換えることができます。それに応じて、彼はAESキーを知っていて、すべてのデータを復号化することができました。
  2. データの完全性/信頼性については触れません。 ECBモード をAESに使用したいようです(これは本当に使用したくない)。 AES-GCM を使用して、バルク暗号化を行います。また、RSAの使用方法についても触れていません。 RSA-OAEP を選択する必要があります(RSAの教科書ではありません)。ただし、実装でこれを実行したと思います。
  3. あなたはデバイスに非常に大きなワークロードをかけました。デバイスは、接続ごとに新しい秘密RSAキーを生成する必要があります。これは、非常に計算負荷の高いタスクです。 ECDH鍵交換の使用を検討する必要があります。
  4. パスワードの検証が機能するためには、サーバーにパスワードをプレーンテキストで保存するか、パスワードを自分でハッシュする必要があります。これにより、サーバーでDoS攻撃が行われる可能性があります。また、中間者攻撃が行われた場合、プレーンなパスワードが攻撃者に明らかにされ、ユーザーに重大な害を及ぼす可能性があります(サイト間でパスワードを再利用する可能性があるため...)
12
SEJPM
  1. デバイスは秘密RSAキーを生成し、公開キーをサーバーに送信します。

  2. サーバーはユーザー固有のAESキーを生成し、RSA公開キーを使用してそれを暗号化してデバイスに送り返します。

  3. デバイスはAESキーを取得します。これを使用してパスワードとユーザー名を暗号化し、サーバーに送信します。

匿名の鍵交換。

認証はありません。鍵交換は暗号化されていますが、認証されていません。これは悪いです。

アクティブな中間者がいる場合、これを検出する方法はありません。このアクティブなMitMは、クライアントがサーバーであるかのように見せかけることができます。そして、サーバーになりすまして、彼がクライアントであると言います。

->しないでください。 @SEJPMは彼のコメントで正しいです。確立された暗号化システムを使用します。証明書付きTLSまたはSRP付きTLSと同様です。

5
StackzOfZtuff