1

私は iOS アプリを開発していますが、サーバーから返されたデータを自分のアプリだけが読み取ることができるようにしたいと考えています。

そこで、自己署名証明書を作成し、Tornado で https を次のようにセットアップします。

http_server = tornado.httpserver.HTTPServer(applicaton, ssl_options={
    "certfile": os.path.join(data_dir, "mydomain.crt"),
    "keyfile": os.path.join(data_dir, "mydomain.key"),
})

http_server.listen(443)

サーバーの API を chrome/safari に入力した後、警告が表示されましたが、データはまだ読み取ることができます。

ブラウザには私の証明書とキーのペアがありません。どうして私のサーバーにアクセスしてデータを読み取ることができるのでしょうか?

公的/私的理論によると:

  1. ブラウザは、証明書に含まれる公開鍵を送信する必要があります
  2. サーバーが何らかの方法で証明書を信頼する場合、サーバーはブラウザの公開鍵を使用して応答を暗号化します
  3. ブラウザは応答を受信し、それ自体の秘密鍵を使用して復号化します

ステップ 2 で、私のサーバーはブラウザの証明書を信頼すべきではありません! 私は正しいですか?

ありがとう。

4

3 に答える 3

3

公的/私的理論によると:

  1. ブラウザは、証明書に含まれる公開鍵を送信する必要があります
  2. サーバーが何らかの方法で証明書を信頼する場合、サーバーはブラウザの公開鍵を使用して応答を暗号化します
  3. ブラウザは応答を受信し、それ自体の秘密鍵を使用して復号化します

いいえ、そうではありません。

サーバー認証のみを使用する SSL/TLS (ほとんどの HTTPS サイト) では、サーバーが最初に証明書を送信し、クライアントが証明書を信頼するかどうかを確認し、クライアントとサーバーがサーバーの公開鍵を使用して共有シークレットをネゴシエートします (どのように行われるかは、サーバーによって異なります)。 cipher suite) を使用し、この共有シークレットから派生したキーを使用して、暗号化されたチャネルが設定されます。

相互認証を使用する SSL/TLS では、追加の手順として、クライアントが証明書をサーバーに送信し、ハンドシェイクの最後に何かに署名して、実際にこの証明書の所有者であることをサーバーに証明します。

ブラウザが証明書と秘密鍵を持っているのは 2 番目のケースのみであり、どのような場合でも暗号化に使用されることはありません。

ここで使用しているコードは と のみをセットアップしcertfileますkeyfile。これは、サーバーのみが認証される接続用にサーバーを構成したことを意味します。ブラウザーの警告をバイパスしているときは、サーバー証明書を信頼するように指示しているだけなので (この場合は自己署名されているため)、接続は実際に続行できます。

クライアントを認証する場合は、クライアント証明書を要求 (および要求) するようにサーバーを構成する必要があります。また、クライアント (ブラウザーかアプリか) でクライアント証明書 (秘密鍵を使用) をセットアップする必要があります。これは、サーバー証明書とその秘密鍵とは無関係です。

Tornado のドキュメントでは、ssl_optionsパラメーターがssl.wrap_socketoptionscert_reqsを使用しているように見えるため、クライアント証明書認証 (特におよび)を使用する場合は、それらを調べる必要がありますca_certs

一般に、クライアント証明書を使用した (アプリのユーザーではなく) アプリの認証は、誰もアプリを逆コンパイルできない場合にのみ機能することに注意してください。アプリには何らかの方法で秘密鍵が含まれているため、誰かがそれを手に入れることができます. もちろん、アプリのすべてのコピーに同じ秘密鍵を使用すると、この問題はさらに悪化します。

于 2013-04-18T16:25:18.980 に答える