I'm working on an application for iOS which will have the user fill out their password. The password will then be posted to a PHP page on my site using either POST or GET. (It must be plaintext because it is used in a script.)
Besides HTTPS, is there any way to secure the password? Encrypt it in Obj-C and then decrypt it in 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.
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).
The password you store in your database is abc(password + salt)
(store the salt
separately)
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))
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.
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 a good defense against a number of attacks.
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.
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. 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. 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. 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.