web-dev-qa-db-ja.com

RSAを使用して新しい公開鍵と秘密鍵を生成する必要があるのはいつですか?

巨大なオンラインモバイルゲームを作成しています。暗号化とネットワークを介したデータの安全な送信に関する私の知識は少し貧弱なので、皆さんにいくつか質問があります。

いくつかの詳細:

  • 各ユーザーはアカウントを持っています
  • ログインするには、ユーザー名とパスワードを入力する必要があります(Webブラウザーではなくアプリを使用)
  • データは、クライアント(モバイルデバイス)からサーバーのどこかに転送されます。

シンプル! Ok私が知っているように、通常のWeb認証はSSLによって保護されています。これは「単純に送信するだけで安全です」です。

モバイルではSSLを使用できません(Androidがいくつかのメソッドを提供している場合でも、ゲームをiOSに移植したり、さまざまなゲーム/ネットワークエンジンを使用したりすることはできません)。

「送信と受信」プロセスを安全にして、第三者がユーザーの資格情報を取得できないようにする必要があります。

私が読んだように、これを実行する最良の方法は、公開鍵と秘密鍵を使用してパケットを暗号化/復号化する[〜#〜] rsa [〜#〜]メソッドです。

私の知識からそれは次のように機能します:

  • 秘密、公開、メッセージという2つのキーがあります。「メッセージ」です。
  • 誰でも公開鍵を入手できる(公開されているため)
  • サーバーのみが秘密鍵にアクセスできます
  • 誰でも公開鍵で「メッセージ」を暗号化でき、それは常に同じに見えます(同じ公開鍵で暗号化された同じメッセージ)
  • 暗号化されたメッセージは、1つの方法でのみ復号化できます-秘密鍵を使用すると、最初のメッセージ「message」のようになります。
  • 公開鍵と秘密鍵は等しくありませんが、異なる暗号化/復号化アルゴリズムを使用しているため、最後にメッセージが同じになるという魔法のように機能します

間違っている場合は修正してください!

そしてこれが私の質問です:

  • 上記の例では、この方法で送信されたパケット(および公開キーが実際に公開されている)は保護されています(もちろん、何でも復号化できます)が、「安全」ですか?
  • 各ユーザーは独自のキーのペアを持っている必要がありますか?
  • いつ新しいキーのペアを生成する必要がありますか?ログインごとに?
  • ユーザーに公開鍵を送信する必要があるのはいつですか?彼が「登録」または「ログイン」をクリックすると(すでにテキストフィールドにデータが入力されています)?または彼がアプリを開いたとき?

これらのことを少し説明できる人がいてくれたらありがたいです! :)

@ Luke Parkへの2つの追加の質問

公開鍵は公開されており、ネットワーク経由で送信しないでください。それは、公開鍵を使用すると、ユーザーが何らかの方法でデータを復号化できることを意味しますか?

2つ目:公開鍵をアプリケーションにバンドルする必要があるとおっしゃいました。公開鍵もハッカーの手に渡る危険なツールである場合、それをコードに保存することは賢明ですか?私が知っているように、コンパイルされたプログラムからデータを取得する方法があります。

そしてもう一つ!キーがバンドルされている(おそらくハードコードされている)場合-常に同じままにする必要がありますか、それともペアを変更する必要がありますか(新しいものを生成する)?どこかで読んだように、公開キーを「公開」することで、データを解読することができます(時間がかかりますが、可能です)。

5
Jacob

一般的に、いくつかの誤解があれば、あなたの言ったことは正しいです。主な違いは、暗号文(たとえば、公開鍵でメッセージを暗号化した後)が常に同じであるとは限らないということです。RSAは、ランダムテキストとパディングを導入します。これはおそらく問題の原因にはなりませんが、セキュリティに貢献します。

個人的には、TLSを機能させるための取り組みは、独自のソリューションを実装するよりも価値があると思います。ただし、自分でやりたい場合は...

ユーザーごとに新しいキーペアを生成しません。単一のサーバー鍵ペアで十分です。アプリケーションとともに公開鍵を配布し、サーバーに秘密鍵を保持します。 RSAを使用してログインデータを暗号化するのではなく、AESキーをネゴシエートし、それを使用してデータを暗号化します。これはTLSで使用される基本的な概念です。これが行われる理由の1つは、RSAで暗号化できるプレーンテキストのサイズがキーのビットサイズによって制限されるためです。通常、RSAを複数回適用せずに240バイト以上を暗号化することはできません。これは、速度とセキュリティの両方の観点からは得策ではありません。

HMACまたはGCMのような認証モードを使用して、データを適切に認証することを忘れないでください。そうしないと、ペイロードが転送中に変更される(読み込まれない)可能性があります。

アプリに公開鍵を送信しないでください。アプリにバンドルする必要があります。安全でないチャネルを介して公開鍵をアプリに送信する場合、転送中に変更されることを止めるものは何もありません。攻撃者は、それを自分の公開鍵に置き換えてから、トラフィック(およびログイン詳細)を自分の秘密鍵で復号化する可能性があります。

もう一度言いますが、TLSは独自のものを実装するよりも優れており安全ですが、これは不可能だと思っているようです。

編集:私は、ネットワークを介して公開キーを送信しないと言います。それは、「危険」または悪意のある資産であるためではなく、プレーンテキストで(たとえば、生のHTTPまたはTCPを介して)公開キーを送信しているためです。誰もがこのトラフィックを変更できるため(それを確認できることは問題ではありません)、アプリに到達する前に、公開鍵を独自の公開鍵に置き換えることができます。キーがすでにアプリにバンドルされている場合、両方の当事者はすでに自分のキーを持っています(たとえば、アプリはパブリックで、サーバーはプライベートです)。

公開鍵は、暗号化と検証以外の目的には役立ちません。それはあなたが隠す必要があるものではありません。それが正しい公開鍵であることを確認できる必要があるだけです。これをアプリにバンドルすると、App StoreとPlay Storeで採用されているセキュリティで、アプリを使用するユーザーのデバイスに十分に到達します。

5
Luke Park