1

I am developing an iOS app, and I want the data return by my server can only be read by my app.

So, I create self-signed certificate, and setup https in Tornado like this:

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)

When after I type the API of my server in chrome/safari, they warned me, but the data still can be read.

The browsers don't have my certificate/key pair, why can they access my server and read the data?

According to public/private theory:

  1. the browser have to send its public key, which involved in its certificate
  2. if my server trust the certificate by some ways, my server encrypt the response using the browser's public key
  3. browser receive the response and decrypt it using itself's private key

In step 2, my server should not trust the browser's certificate! Am I right?

Thanks.

4

3 回答 3

3

According to public/private theory:

  1. the browser have to send its public key, which involved in its certificate
  2. if my server trust the certificate by some ways, my server encrypt the response using the browser's public key
  3. browser receive the response and decrypt it using itself's private key

No, that's not how it works.

In SSL/TLS with only server authentication (most HTTPS sites), the server sends its certificate first, the client checks whether it trusts the certificate, the client and server negotiate a shared secret using the server's public key (how it's done depend on the cipher suite), and an encrypted channel is set up, using keys derived from this shared secret.

In SSL/TLS with mutual authentication, an extra steps involves the client sending its certificate to the server and signing something at the end of the handshake, to prove to the server it's indeed the holder of this certificate.

It's only in the second case that the browser has a certificate and a private key, and it's never used for any encryption in any case.

The code you're using here only sets up certfile and keyfile, which means you've configured your server for a connection where only the server is authenticated. When you're bypassing the browser warning, you're merely telling it to trust the server certificate (since it's self-signed in your case), so the connection can indeed proceed.

If you want to authenticate the client, you'll need to configure the server to request (and require) a client certificate. You'll also need to set up the client certificate (with its private key) in the client (whether it's the browser or your app). This is independent of the server certificate and its private key.

The Tornado documentation seems to indicate the ssl_options parameter uses the ssl.wrap_socket options, so you should look into those if you want to use client certificate authentication (in particular cert_reqs and ca_certs).

Note that, in general, authenticating an app (as opposed to the user of an app) using a client certificate only works as long as no-one is able to decompile the app. The app will contain the private key one way or another, so someone could get hold of it. This problem is of course even worse if you use the same private key for all the copies of your app.

于 2013-04-18T16:25:18.980 回答
0

我在这个领域绝不是知识渊博,但证书只是为了帮助确保服务器就是它所说的那个人。

如果他们信任服务器证书,任何人都可以查看该页面。

要获得所需的功能,您可能需要使用某种形式的身份验证,甚至是基本的身份验证,例如 HTTP 标头字段中的给定值。

于 2013-04-17T15:25:02.573 回答
0

这是一个奇怪的提示,您只需破解您的用户代理,因此龙卷风只会允许您提供的字符串,我不知道 iOS 浏览器是否提供此功能,但在 PC 上的 Chrome 中,您可以在 开发人员工具->设置中覆盖您的用户代理- >覆盖

利用:

self.request.headers["User-Agent"]

因为它是一个字符串,那么你只允许一些字符串通过:

if personnalized_ua not in self.request.headers["User-Agent"]:
    self.redirect("no-way.html")

现在,如果您只想访问 iPhone,请使用user_agents 库

于 2013-04-18T15:03:47.100 回答