简体   繁体   English

安全地发送纯文本密码?

[英]Securely send a Plain Text password?

I'm working on an application for iOS which will have the user fill out their password. 我正在开发一个iOS应用程序,用户可以填写密码。 The password will then be posted to a PHP page on my site using either POST or GET. 然后使用POST或GET将密码发布到我站点上的PHP页面。 (It must be plaintext because it is used in a script.) (它必须是纯文本,因为它在脚本中使用。)

Besides HTTPS, is there any way to secure the password? 除了HTTPS,有什么办法可以保护密码吗? Encrypt it in Obj-C and then decrypt it in PHP? 在Obj-C中加密,然后在PHP中解密?

NOTE: The username is not sent... only the password is posted to the server. 注意:不发送用户名...只有密码被发布到服务器。

EDIT: To clarify, David Stratton is correct... I'm trying to prevent malicious sniffers in public locations from simply reading clear text passwords as they are posted to the server. 编辑:澄清一下,David Stratton是正确的......我试图阻止公共场所的恶意嗅探器在发布到服务器时简单地读取明文密码。

Challenge response outline 挑战响应大纲

Lets assume you have one-way hash function abc (in practice use md5 or sha1 a cryptographically strong hashing algorithm for PHP see: password_hash ). 让我们假设您有单向散列函数abc (实际上使用md5sha1加密的强哈希算法,请参阅: password_hash )。

The password you store in your database is abc(password + salt) (store the salt separately) 您存储在数据库中的abc(password + salt)abc(password + salt) (单独存储salt

The server generates a random challenge challenge and sends it to the client (with the salt ) and calculates the expected response: abc(challenge + abc(password + salt)) 服务器生成随机挑战challenge并将其发送到客户端(使用salt )并计算预期响应: abc(challenge + abc(password + salt))

The client then calculates: abc(user_password + salt) and applies the challenge to get abc(challenge + abc(user_password + salt)) , that is sent to the server and the server can easily verify validity. 客户端然后计算: abc(user_password + salt)并应用challenge来获取abc(challenge + abc(user_password + salt)) ,该命令被发送到服务器并且服务器可以轻松验证有效性。

This is secure because: 这是安全的,因为:

  • The password is never sent in plaintext, or stored in plaintext 密码永远不会以纯文本格式发送,也不会以明文形式存储
  • The hash value that is sent changes every time (mitigates replay attack) 发送的哈希值每次都会更改(减轻重放攻击)

There are some issues: 有一些问题:

How do you know what salt to send? 你怎么知道送什么盐? Well, I've never really found a solution for this, but using a deterministic algorithm to turn a username into a salt solves this problem. 好吧,我从来没有真正找到解决方案,但使用确定性算法将用户名转换为盐解决了这个问题。 If the algorithm isn't deterministic an attacker could potentially figure out which username exists and which do not. 如果算法不具有确定性,则攻击者可能会找出存在哪个用户名,哪些用户名不存在。 This does require you to have a username though. 这确实需要您拥有用户名。 Alternatively you could just have a static salt, but I don't know enough about cryptography to assess the quality of that implementation. 或者你可以只有一个静态盐,但我对密码学知之甚少,无法评估该实现的质量。

Reconsider not using HTTPS. 重新考虑不使用HTTPS。 HTTPS a good defense against a number of attacks. HTTPS可以很好地防御多种攻击。

There usually isn't a reason to transmit a password. 通常没有理由传输密码。 By transmitting passwords, you are sending valuable data and their is extra risk associated with it. 通过传输密码,您发送的是有价值的数据,并且与之相关的风险更大。

Usually you hash the password and submit the hash. 通常您散列密码并提交哈希值。 On the server side, you compare the hashes, if they match, great. 在服务器端,你比较哈希,如果匹配,很好。

Obviously with this approach, the hash is important, and you have to secure against a replay attack. 显然,使用这种方法,哈希很重要,你必须防止重放攻击。 You could have your server generate a crypto-secure one-time use salt, pass that to the client, salt and hash the password, and compare the hashes serverside. 您可以让您的服务器生成加密安全的一次性使用盐,将其传递给客户端,盐和哈希密码,并比较哈希服务器端。

You also need to guard against a reverse hash attack on password. 您还需要防止对密码的反向哈希攻击。 IE, I have a hash, and I can compare it to a bunch of pre-generated hashes to find the original password. IE,我有一个哈希,我可以将它与一堆预先生成的哈希进行比较,以找到原始密码。

You could encrypt at the device and decrypt at the server, but if the data going across the wire is sensitive enough to warrant that much work, then IMHO, I believe you're better off just using https. 您可以在设备上进行加密并在服务器上进行解密,但如果通过线路的数据足够灵敏以保证那么多工作,那么恕我直言,我相信您最好只使用https。 It's tried, true, and established. 它经过了尝试,真实和成熟。

It's not perfect, mind you, and there have been successful attacks against older versions of it, but it is a heck of a lot better than "rolling your own" method of security. 它是不完美的,请注意,并且已成功攻击它的旧版本,但它比“滚动自己的”安全方法要好得多。

Say your key gets compromized, for example: If you're using https with a cert from a trusted authority, then you just buy a new cert. 假设您的密钥被泄露,例如:如果您使用https和受信任机构的证书,那么您只需购买新证书。 HTe deveice, if it trusts the authority, will accept the new certificate. 如果它信任当局,则会接受新证书。 If you go your own route on it, then you have to update the keys not only on your web server, but at the client as well. 如果您使用它自己的路线,那么您不仅要在Web服务器上更新密钥,还要在客户端更新密钥。 No way would I want that sort of headache. 我不希望那种头痛。

I'm not saying that the challenge is insurmountable. 我并不是说挑战是不可克服的。 I am saying it may not be worth the effort when tools already exist. 我说当工具已经存在时,可能不值得努力。

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

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