简体   繁体   English

如何与服务器安全通信?

[英]How to securely communicate with server?

I'm building a solution consisting of an app and a server. 我正在构建一个由应用程序和服务器组成的解决方案。 Server provides some methods (json) and the app uses them. 服务器提供一些方法(json),应用程序使用它们。 My aim is to make those API methods inaccessible to other clients. 我的目的是使其他客户端无法访问这些API方法。 What is the best way to do so? 最好的方法是什么? Should I take a look at certificates (to sign every outgoing request)? 我应该看看证书(在每个外发请求上签名)吗? If yes, where do I start and what is the performance impact of doing so? 如果是,我从哪里开始,这样做对性能有何影响? What are alternatives? 什么是替代品?

Put another way, you need a way to distinguish a valid client's request from an invalid client's request. 换句话说,您需要一种区分有效客户端请求和无效客户端请求的方法。 That means the client needs to present credentials that demonstrate the request comes from a valid source. 这意味着客户端需要提供凭据,以证明请求来自有效来源。

SSL certificates are an excellent way to assert identity that can be validated. SSL证书是断言可以验证的身份的绝佳方法。 The validity of an SSL certificate can be confirmed if the certificate contains a valid signature created by another certificate known to be secure, a root cert. 如果SSL证书包含由另一个已知安全的证书(根证书)创建的有效签名,则可以确认SSL证书的有效性。 As noted in other answers an embedded certificate won't do the job because that certificate can be compromised by dissecting the app. 如其他答案中所述,嵌入式证书无法完成任务,因为该证书可能会因解剖应用程序而受到损害。 Once it is compromised, you can't accept any requests presenting it, locking out all your users. 一旦遭到入侵,您将无法接受任何提出该请求的请求,从而将所有用户锁定在外。

Instead of one embedded app cert, you need to issue a separate certificate to each valid user. 您需要向每个有效用户颁发单独的证书,而不是一个嵌入式应用程序证书。 To do that, you need to set up (or outsource to) a Certificate Authority and issue individual, signed certificates to valid clients. 为此,您需要设置(或外包给)证书颁发机构,并向有效客户端颁发单独的,已签名的证书。 Some of these certificate will be compromised by the user -- either because they were hacked, careless or intentionally trying to defraud your service. 这些证书中的一些会被用户破坏-要么是因为它们被黑客入侵,粗心大意,要么是故意欺骗您的服务。 You'll need to watch for these stolen certificates, place them on a certificate revocation list (CRL) and refuse service to these compromised certificates. 您需要注意这些被盗的证书,将它们放置在证书吊销列表(CRL)中,并拒绝提供对这些受到破坏的证书的服务。 Any web server is able to refuse a connection based on a CRL. 任何Web服务器都可以拒绝基于CRL的连接。

This doesn't solve the security issues, it just moves them out of the app. 这不能解决安全问题,只是将它们移出应用程序。 It is still possible for someone to create what appears to be a valid certificate through social engineering or by stealing your root certificate and manufacturing new signed certificates. 有人仍然可以通过社会工程或窃取您的根证书并制造新的签名证书来创建看似有效的证书。 (These are problems all PKI providers face.) (这些是所有PKI提供商都面临的问题。)

There will be a performance hit. 将会影响性能。 How much of a hit depends on the number of requests from the app. 命中多少取决于应用程序发出的请求数量。 The iPhone NSURLConnection class provides support for SSL client certificates and client certificates can be installed in the phone from an e-mail or authenticated web request. iPhone NSURLConnection类提供对SSL客户端证书的支持,并且可以通过电子邮件或已验证的Web请求将客户端证书安装在电话中。 Managing the infrastructure to support the client certs will require more effort than coding it into the app. 管理基础架构以支持客户端证书将需要比将其编码到应用程序中更多的工作。

Incidentally, voting down any answer you don't like creates a chilling effect in the community. 顺便说一句,拒绝您不喜欢的任何答案都会给社区带来寒蝉效应。 You're not nearly as likely to get advice -- good or bad -- if you're going to take a whack at everyone's reputation score. 如果您要对每个人的声誉得分大加赞赏,那么您获得建议的可能性就不大可能是好是坏。

I will now freely admit that it's an interesting question, but I have no idea how it could be done. 我现在可以自由地承认这是一个有趣的问题,但是我不知道如何实现。

Original answer: 原始答案:

Interesting question. 有趣的问题。 Assuming people can't reverse-engineer the iPhone app, the only solution that comes to mind would be to sign requests with a public key, or some other secret known only to the application. 假设人们无法对iPhone应用程序进行逆向工程,那么想到的唯一解决方案就是使用公共密钥或仅应用程序已知的其他秘密对请求进行签名。 By that, I mean adding an extra argument to every API call that is a hash of the destination URL and other arguments combined with a secret known only to your server and application. 通过这种方式,我的意思是向每个API调用添加一个额外的参数,该参数是目标URL和其他参数的哈希,并结合了仅服务器和应用程序已知的秘密。

To expand upon this: suppose your API call has arguments foo , bar and qux . 对此进行扩展:假设您的API调用具有参数foobarqux I would add a signature argument, the value of which could be something as simple as sorting the other arguments by name, concatenating them with their values, adding a secret, and hashing the lot. 我要添加一个signature参数,该参数的值可以像按名称对其他参数进行排序,将它们与它们的值连接在一起,添加一个秘密并进行哈希处理一样简单。 Then on the server side, I would do the same thing (excepting the signature argument) and check that the hash matches the one we were given in the request. 然后在服务器端,我将做同样的事情(除了signature参数),并检查哈希是否与请求中给出的哈希匹配。

Consider authenticated HTTP. 考虑经过身份验证的HTTP。

For a cheaper alternative, there's shared secret/hash scheme. 对于更便宜的替代方案,有共享的秘密/哈希方案。 The client and the server have a shared secret string of text. 客户端和服务器具有共享的文本秘密字符串。 Upon request, the client hashes together (using MD5, or SHA1, or SHA something else - you choose) the request fields and the secret. 根据请求,客户端将请求字段和密码散列在一起(使用MD5或SHA1或SHA进行其他选择)。 The hash value is attached to the request - say, as another POST field. 哈希值附加到请求-例如,作为另一个POST字段。

The server does the same operation with the request and with its copy of the secret, then compares the hash values. 服务器对请求及其机密副本执行相同的操作,然后比较哈希值。 If they don't match - service denied. 如果不匹配-服务被拒绝。

For added security, you may encrypt the hash with a RSA public key. 为了提高安全性,您可以使用RSA公钥对哈希进行加密。 The client has the public key, the server keeps the private key. 客户端具有公钥,服务器保留私钥。 The server decrypts the hash with the private key, then the same. 服务器使用私钥解密哈希,然后对其进行解密。 I did that with a C++ WinMobile client and a PHP-based service - works like a charm. 我使用C ++ WinMobile客户端和基于PHP的服务来做到这一点-就像一个魅力。 No experience with crypto on iPhone, though. 但是,没有在iPhone上使用加密的经验。

UPDATE: now that I think of it, if we assume that the attacker has complete control over the client ( ahem jailbroken iPhone and a debugger), the problem, as formulated above, is not solvable in theory. 更新:现在我想到了,如果我们假设攻击者完全控制了客户端( 狱的iPhone和调试器),那么上述问题在理论上就无法解决。 After all, the attacker might use your bits to access the service. 毕竟,攻击者可能会使用您的比特来访问服务。 Reverse-engineer the executable, find the relevant functions and call them with desired data. 对可执行文件进行逆向工程,找到相关功能并使用所需数据调用它们。 Build some global state, if necessary. 如有必要,建立一些全局状态。 Alternatively, they can automate your UI, screen scraper style. 或者,他们可以自动执行您的UI(屏幕抓取样式)。 Such is the sad state of affairs. 这是令人伤心的事态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM