I'm putting together an android client (and possibly in the future iOS, web portal, etc) and php mysql server. Server side I am currently using the PHPass library to hash and salt the incoming passwords.
Should I make the client send plain text passwords over HTTPS/SSL or should the client do some form of hashing first. For example should every client simply sha1 (or some other algorithm) every outgoing password?
Most websites will send the password plain-text over an encrypted connection SSL/HTTPS. Hashing the password client-side can be done, but the advantage is small and often client-side languages (JavaScrypt) are slow so you can calculate less rounds in the same time, what weakens the hash. In every case the server must calculate a hash as well to be safe.
The advantage is small, because if an attacker can do a ManInTheMiddle attack, he can also modify/remove the script (JS) which does the hashing. Only an encrypted connection with SSL/HTTPS can protect against a MITM attack, so you need SSL anyway.
In your case with an app, it looks slightly different. Because the user first has to install your software, there is no need to send a script to the client, so a MITM cannot modify this script. Moreover, the app can calculate the hash relatively fast (if it can run native code) and therefore can do enough rounds on client-side.
This is what i would do:
For easiness send the password plain-text over an encrypted SSL/HTTPS connection and calculate the slow BCrypt hash server side, as you do now.
Only if the load on the server grows too heavy, then you can move the calculation of the slow BCrypt hash to the client app. Still use HTTPS to send the hash, and then calculate an additional fast hash (e.g. SHA-256) on the server. This is more complex, because you have to exchange and store the salt separately.
Another disadvantage of hashing passwords on the client is that you cannot change the hashing algorithm or iteration count without also having to update your clients.
For JavaScript clients that is not a problem, but you cannot easily guarantee that your users will be on the most recent version of your native client.
So I would stick with sending plain passwords over HTTPS.
In the early days of HTTP, there was Digest authorization as an alternative to Basic authorization. Instead of the HTTP header
Authorization: Basic <credentials>
you would use
Authorization: Digest <credentials>
It was an algorithm that increased security by avoiding the password being sent as cleartext. This was in the days when TLS/SSL came at a performance cost so this was an alternative. However the algorithm meant the password had to be stored as cleartext on the server. So you had a choice of sending the password cleartext but having a hash on the server, or sending the password as a hash but having cleartext on the server.
Unsurprisingly, as martinstoeckli said in his answer, now that TLS/SSL is widespread and easy to implement, HTTPS is used instead. You can store the password as a hash on the server but not expose the plaintext password if it is intercepted by a MITM attacker.
Related
I am working on a mobile app using Corona SDK. One of its core functionalities requires sending data between the app and my server. My question is, at what point do my attempts at making the data transfer secure become redundant?
The server side consists of a few PHP files and a single MySQL database. I have an SSL certificate and I validate the data at both ends. The app itself only makes network requests via HTTPS/SSL using HTTP POST and the data being transferred is a JSON string.
To this point, I believe that I have done everything as they should be done. However, as an extra precaution, I also encrypt and decrypt the JSON string at both ends using AES256-CBC.
Is this extra encryption at all necessary or is it redundant?
HTTPS protects the transport between the client (browser) and the server. It specifically does not protect data at rest at the server side (i.e. inside the database) not does it protect the transfer of the data between the PHP application to the database.
It is unclear if any protection outside the transport between client and server is needed. But it seems that your AES encryption will only protect the same path as HTTPS already does. In this case it will likely not add any protection. It might maybe add protection against legal (or malicious) SSL interception but if the encryption key is send over the same communication channel as the encrypted data then it will not actually add protection.
I need to capture client's passwords for a third party account on a web form.
I have a dedicated server and SSL installed.
My plan was to have the user submit the form to the PHP processing script.
The PHP processing script will encrypt the password using aes-256-ctr and then save it to a randomly generated filename in a write only folder on the server (below the public_html folder).
I will get an alert when a new one is added and will immediately scp the encrypted file to my local machine and delete it from the server.
I can then decrypt the file locally.
How secure is this?
No that is not a secure method of securing the passwords. Security is not gained by keeping the method secret.
If you must save the actual passwords here is one method to reduce the vulnerability:
Consider using an HSM for encryption the passwords, they are not cheap.
Store the passwords on a separate server not connected to the Internet.
Have only a connection to the server that needs the passwords.
Use a simple API to set, request and delete the passwords.
Use 2-factor admin authentication and limit the admins to no more than two trusted people.
Use serial numbered tokens for the 2-factor authentication, not email or text messaging, that way you have positive control of the number of admins.
Use rate-limiting on the server and provide alerting if the rate is exceeded.
Hire a cryptographic SME to vet the design and implementation.
Use 2-factor admin authentication on the Internet connected server.
Buy liability insurance.
One major security issue is that many of the users will re-use passwords with other systems. Your system will be breached and user information and passwords will be stolen and you will not know that has happened. These user credentials will be used to gain access to users information on other systems. Your liability is potentially huge.
Warning: I am not a SME on this topic.
For private use only, I'm creating and hosting on my web server a PHP application that retrieves all my passwords for various accounts from a MySQL database and serves them to the client that is an iPhone application which should also be able to insert new passwords in the database.
Instead of sending this data over the internet as plain text I would like to encrypt them before sending them but I'm very new to encryption so I'm feeling a little bit disoriented among all the possible encryption algorithms out there.
While the mcrypt function on PHP seems to be very flexible and compatible with many encryption algorithms I couldn't find anything like that on iOS.
What I wanted was some algorithm easy to implement both on PHP and Objective-C that, given some plain text and an encryption key (stored both on the server and on the client), would encrypt AND decrypt the plain text.
For further detail the server/client communication I had in mind was something like this:
Client sends a request containing some client-specific-app-ID and the service
whose password the server should return
The server checks if that client ID is allowed to get that information
If the client is allowed then the server querys the database and
retrieves the password
The server encrypts the password and sends it to the client
The client decrypts the password and shows it to the user
This thing is for personal use only so I don't need unbreakable security because probably nobody will care breaking it.
I'm doing this just for research and to get started with encryption. I know this is not secure at all.
Do you guys know any two-way encryption algorithm that is easy to use both on php and objective-c that I can use to encrypt passwords on the server and decrypt them in iOS?
Don't bother with your own encryption. You just need to use an SSL link, e.g.
https://yourserver.example.com/getpasswords.php
^---
SSL gives you the encryption for free, and as a bonus allows the iOS client to be reasonably sure that it's connecting to YOUR server, and not some malicious fake server.
I'm building a website that will require registration and login.
Since I'm new to web developing, i was thinkink if sending unencrypted passwords to the server is an option.
Or, what you would reccomand me, since I don't know nothing about cryptography?
Edit: http://pastebin.com/nYcazcZq
If your website is just for testing or for use within the intranet, it's not that big of a deal.
If not, I highly suggest you use SSL.
If you can't afford the certificate, at least give your users the option to :
login with OpenID (as most OpenID providers offer SSL for authentification) ;
login using Digest Authentication (which doesn't send the passwords in clear over the network).
If you mean sending from browser to your server, then you need to use https/ssl to encrypt the connection, not the password itself. If on the other hand you're talking about storing passwords plaintext, then yes, that's bad as well. You should hash it with a strong salt (per user is best) and a slow algorithm.
This answer goes into more detail about sending passwords over SSL : Sending passwords over the web
You can use PHP's crypt for hashing : http://php.net/manual/en/function.crypt.php
Keep in mind that even when your service doesn't have any kind of valuable payload, it is guaranteed that many of your users will use the same password with it that they use with something more valuable, which means a breach or an easily-intercepted password on your end is capable of causing harm. Even if this is bad practice on the user's part, it's an unavoidable fact of life, so there is really no circumstance under which it is responsible to be blasé about user credentials with a publicly-accessible service. Please use SSL/https or OpenID (or another externally-hosted login management scheme, even Facebook: how to use facebook for user login on my website?) and if you are the password holder, please don't save them in the db as plaintext.
It is never good to send password unencrypted. For a serious web site you should encrypt the traffic between the browser and server using https. You do that by purchasing a certificate that you install on the web server.
never send raw critical data on net,using ssl is best solution i think,also you can use javascript encryptor to encrypt password in client side and decrypt in server,
We have the following:
iPhone native app, with login form that posts to:
A php script on remote web server which checks against MySQL user table.
For security, would it be best practice to use some two-way encryption to encrypt every request? including this initial login? otherwise the user and pass will simple be passed to the web app in the clear?
I suppose https would take care of it automatically...
It would be very wise to use SSL or TLS (the protocols that HTTPS uses) to communicate with the server. You could likely get this set up rather easily on a *nix or Windows server using OpenSSL. If you're on a shared host, they likely have an option to purchase an SSL certificate that's valid for a given period of time. This is a fairly trivial process and usually requires about a week (average) with most hosts to get set up.
It should also be noted that while it is never a bad idea to encrypt the login process, it will not make your system more secure "over all" if you have a login from the web that is not secured. For instance, if you secure communication with mobile devices, but not with desktops or laptops, your security may be for nigh. The security of your application is only as strong as its weakest link, so securing your entire application (for all platforms) is very important.
Also, keep in mind that a user's login credentials are only as valuable as the data or resources that they protect: if you encrypt the login information, it is also a good idea to encrypt the rest of the application as well. Wireless sniffing technology could easily steal session data, private user information, or other sensitive data. Securing the entire user session--rather than just the login procedure--is in your users' best interest.
Hope this helps!
Using https is probably the way to go. It's what it was designed for.