如何加密通过 TCP 传输的密码?
在我的游戏应用程序中,从 iPhone/iPad 运行到我通过 TCP 控制的中央服务器,我需要发送登录信息。
我目前所做的是发送一个带有 ascii 字节的 LOGIN 操作码,用于明文登录和密码。我不想以明文形式发送用户的密码 - 例如,它们可能位于 wifi 连接上。
我该如何处理这个加密?以下是我的要求:
- 我不想使用第三方库,如果绝对必要的话我会使用。如果有必要,它必须是 BSD 许可证或类似许可证
- 我对应用商店的“您的应用程序是否有加密技术”回答“是”有什么影响
- 我希望每个国家/地区都可以使用此应用
- 在设备本地对密码进行哈希处理并仅发送该缓存值是否可以接受?用户的帐户可能会因哈希值被盗而受到损害,但密码不会丢失(而且我不会存储他们的密码)..
- 我无法进行某种 OAuth 应用程序外设置正如我以前经历过的那样,它太具有侵入性了,
我在这里有点不知所措。我很感谢这里的任何好的帮助,因为这是我在结束近一年的开发之前需要解决的最后三件事之一..(所以这不是理论上的或过早的优化!它已经发展成为一个实际问题..)
In my game app, running from iPhone/iPad to a central server that I control via TCP, I need to send login information.
What I currently do is send a LOGIN opcode with ascii bytes for login and password in the clear. I don't want to send user's passwords in the clear - they could be on a wifi connection for example.
How can I handle encryption of this? Here are my requirements:
- I don't want to use a 3rd party lib, I will if absolutely necessary. If necessary it has to be BSD license or similar
- What's the impact of me answering "yes" on "does your App have cryptography in it" to the App store
- I want this app to be available in every country
- Is it acceptable to, locally on the device, hash the password, and send that cached value only? The user's account could be compromised by the hash being stolen, but the password wouldn't be lost (and I wouldn't be storing their passwords)..
- I can't have some kind of OAuth out-of-the-app setup system done as I've experienced before, it's too invasive
I'm sort of at a loss here. I appreciate any good help here as this is one of the last 3 things I need to address before ending almost a year of development.. (so this isn't theoretical or premature optimizing! it has grown in to an actual issue..)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,义务:“不要发明自己的密码方案。如果你不是专家,你就会做错。如果你是专家,你就会以一种创造性的方式做错,这种方式非常糟糕,但除非您的方案被成千上万的人使用,否则破坏将是看不见的。”
接下来,明确您想要保护的内容以及原因。您提到明文用户密码由于某种原因是不好的。您是否担心用户在很多地方使用的密码会被您的应用程序泄露,从而危及用户的其他帐户,或者您是否更担心攻击者能够访问您的用户帐户?
我对我在哈希思想的潜台词中读到的内容的担忧是,客户端发送的哈希永远不会改变(除非密码更改)。这使得它相当于明文的身份验证(攻击者只需要窃取哈希值;然后他们就可以在不知道密码的情况下进行身份验证)。它还使密码更容易受到可以看到哈希值的人的暴力攻击。
我的印象是您希望避免加密,因为担心它会限制应用程序的可用性。我能理解这个理由。
让我们假设加密安全哈希不是密码学(我不知道它是否是,但据我所知,就美国出口限制而言,它不是)。我的建议是使用一个非常简单的质询响应协议来验证用户是否拥有密码(我建议您在线查找“质询响应协议”)。
这里需要注意的是,我一开始并没有解决获取服务器密码的问题。只是服务器验证用户是否拥有正确的帐户密码。将此视为如何防止重放攻击之类的事情的一般想法,并使可以看到数据流的攻击者的生活变得更加困难:
客户端:“我希望以 John Smith 身份进行身份验证”
服务器:“好的'John Smith' -claiming-person,获取当前日期和时间(2011-09-09@12:04:33AM)和我刚刚想到的随机数:4bazillion,并使用您的密码对它们进行哈希处理,让我知道您的内容。 得到。”
客户端:
服务器:
First, the obligatory: "Don't invent your own password scheme. If you aren't an expert, you will do it wrong. If you are an expert, you will do it wrong in a creative way that is horribly broken but which brokenness will be invisible until your scheme is in use by thousands"
Next, be clear about what you want to protect, and why. You mention plaintext user passwords being bad for some reason. Are you concerned that a password the user uses in a bunch of places will be leaked by your application, compromising the user's other accounts, or are you more concerned that the attacker will be able to gain access to your user's account?
My concern with what I read in the subtext of your hashing idea is that the hash that the client sends will never change (unless the password changes). This makes it a plaintext-equivalent for authentication (the attacker need only steal the hash; they can then authenticate without knowing the password). It also makes the password a little more vulnerable to brute-force attacks by someone who can see the hash.
I get the impression that you want to avoid encryption for concerns that it will limit the availability of your application. I can understand that reason.
Let's assume that a cryptographically secure hash isn't cryptography (and I don't know if it is or not, but it isn't in terms of U.S. export restrictions as far as I have read). My suggestion would be a very simple challenge-response protocol to use to verify that the user has the password (I recommend you look up "challenge-response protocol" online).
One caveat here is that I don't address getting the password to the server in the first place; just the server verifying that the user has the correct password for the account. Think of this as a general idea of how you might prevent things like replay attacks, and make life more difficult for attackers that can see the data stream:
Client: "I wish to authenticate as John Smith"
Server: "Okay 'John Smith'-claiming-person, take the current date and time (2011-09-09@12:04:33AM) and a random number I just thought up: 4bazillion, and hash them with your password. Let me know what you got."
Client:
Server:
TLS/SSL。只需使用它即可。它内置于 iOS 中。
至于加密,是的,您需要声明您使用加密,这将要求您从政府获得(简单的)在线注册证书。
TLS/SSL. Just use it. It is built into iOS.
As for encryption, yes, you will need to claim you use encryption, which will require you to get an (easy) online registration certificate from the government.
通过 HTTPs 对您的服务进行身份验证。您不需要使用任何第三方库。您可以将其实现为 post 或 get。
Authenticate with your service over HTTPs. You will not need to use any third party libraries. You can implement this as either a post or a get.