17

I'm developing an application. The user must enter his credentials which will be sent to the server. If the user opens the application a second time he shouldn't need to enter them again - credentials should be stored on user's machine. Also this data can be passed around. My app is cross-platform so I'm searching for a cross-platform solution. So step by step the algorithm should look like this:

  1. The user enters login and a password, and this data goes to the server. How can I securely pass it? Should I use a secure protocol like https or ssl?
  2. If the credentials are correct I need to save this data to the local machine. Should I use a local database file, a binary, or just a text file? Where to store this file? And I bet I need to encrypt this. Also I need to decrypt it later, but for decryption I need some additional data (some key, probably), right? Where to store this additional data?
  3. At some point I need to pass this information to another process. I already have tcp communication between processes established. Is this enough for passing? Should I pass it encrypted or decrypted.

Please correct me if my steps are wrong. This is a first time I'm dealing with security so I'm lacking knowledge.

RoraΖ
  • 12,317
  • 4
  • 51
  • 83
nikitablack
  • 297
  • 1
  • 2
  • 7
  • You refer to `app`, `server` and `another process` as if they are all separate. Can you clarify differences between `server` and `another process`? Between `app` and `another process`? – user2338816 Jan 22 '15 at 00:58

3 Answers3

12

The user enters login and a password, and this data goes to the server. How can I securely pass it? Should I use a secure protocol like https or ssl?

Yes! You need to pass the data in a security way, using TLS for example.

If the credentials are correct I need to save this data to the local machine. Should I use a local database file, a binary, or just a text file? Where to store this file? And I bet I need to encrypt this. Also I need to decrypt it later, but for decryption I need some additional data (some key, probably), right? Where to store this additional data?

You can generate a key instead of the password, so for example, in the authentication the server returns a KEY (random bits) save that in a database with the ID of the user, and you store that KEY localy, but in the server you know who that belongs to. Then, in the second login, you send that key to the server, that checks if its valid (belongs to that user) and not expired.

At some point I need to pass this information to another process. I already have tcp communication between processes established. Is this enough for passing? Should I pass it encrypted or decrypted.

Again, you pass only the key. You can encrypt, but its realy hard to avoid all the types of attacks your system may suffer.

fgpr0x
  • 415
  • 3
  • 8
  • 1
    Thank you. Sorry, but I didn't understand why to use a KEY instead of a password. This KEY can be extracted by a third person the same way as a password. – nikitablack Jan 21 '15 at 12:25
  • 1
    The key would prevent the attacker of knowing the password. That been said, this key should only let the software log into the user account. – fgpr0x Jan 21 '15 at 12:41
  • 2
    plus, if you are really using TLS you can 'avoid' network intercept, but if an attacker has local access to the computer, then the only thing you can do is to make it hard, but not impossible to capture. – fgpr0x Jan 21 '15 at 12:44
  • 4
    @nikitablack The key can expire whenever a connection is made from another IP or after a certain date (e.g. log in once a month). Both things that are not possible with passwords. – David Mulder Jan 21 '15 at 17:57
10

HTTPS or a custom protocol using TLS for encryption is the correct way to securely communicate with a remote server, assuming you implement it correctly and exit if something isn't right with certificates (I've seen mobile apps that despite using HTTPS, accepted my self-signed certificate right away without even asking the user, making the whole "security" pointless).

Storing the credentials securely on the machine is a lot harder because if your app can decrypt them, so can malware running with the same privileges as your app - any protection would just be security by obscurity and won't stop a dedicated attacker, it may only protect against common "stealers" which are mainly designed to steal browser profiles (history, session cookies) or personal files (for possible identity theft) and won't steal the actual app binary so the attacker won't know how the saved credentials were encrypted, or even if he has the app's binary he may just not care because reverse-engineering is time consuming and requires experience (note that malware developers often aren't the ones who actually deploy them and collect/resell the stolen data).

You may derive a key from the hardware like pbkdf2(sha512(OSname+OSversion+CPUmodel+MACaddress)) and use that as a key to encrypt the credentials, which can be retrieved on the same machine but won't benefit an attacker if he only stole the encrypted credentials and the app's binary unless he has still access to the machine to go back and get that same value

There is no need to use encryption for inter-process communication on the same machine, if an attacker can intercept that communication he already has control of the machine (at the same privilege level that the app uses, if not higher) which means you can read what I said above about not being able to defend against that.

  • Thank you. Can you give an advise about protection for my case - maybe some links or terms, which algorithm is suitable? – nikitablack Jan 21 '15 at 12:31
  • encryption/decryption algorithm. And regarding to derive a key from the hardware - does that means that if the user change hardware the decryption stop to work? – nikitablack Jan 21 '15 at 12:35
  • 1
    @nikitablack use AES for encryption, and yes if the hardware changes the key is no longer the same and your app should fail gracefully and prompt the user for credentials again, to re-encrypt them again using the new key. –  Jan 21 '15 at 12:39
  • 4
    For encryption and decryption with TLS, see [my answer to Now that it is 2015, what SSL/TLS cipher suites should be used in a high security HTTPS environment?](https://security.stackexchange.com/a/77018/39623). For password hashing, see [Thomas Pornin's canonical answer to How to securely hash passwords?](https://security.stackexchange.com/a/31846/39623). If you derive a key from the hardware, **it is predictable, and it can be trivially found out** - the example above can be trivially spoofed as well. Try searching for "Active Directory" or "LDAP" or "Kerberos" credential use instead. – Anti-weakpasswords Jan 21 '15 at 13:43
  • One solution would be to store the key on the server and the encrypted data on the app storage. Then, when the user goes to the app a second time, it sends the encrypted data to the server, the server decrypts it and checks if the data is correct or not. This is how I would do it. – Ismael Miguel Jan 21 '15 at 14:58
  • @IsmaelMiguel that's over complicated and doesn't add any security, you still need some kind of "reference" to send to the server along with the data so the server decrypts it, in this case the reference becomes the key, and now your problem is to securely store that reference, which is again impossible to hide from an attacker with the same privileges as the user. –  Jan 21 '15 at 15:22
  • @AndréDaniel It does add a little security. If the users device is stolen and contacts the app maker, the key can be deleted from the server. Encrypting with a MAC address doesn't add much entropy. The first 24 bits of a MAC address are a manufacturers identifier, and are publicly available. The remaining 24 bits could be easiy brute forced. OS Version offers little additional entropy. – Steve Sether Jan 21 '15 at 16:09
  • @SteveSether you have a good point about revoking the key, but since it looks like the app itself is just a client for an online service, the user can also just change his credentials and invalidate the stored ones even without using the "server decrypts the data" approach. My hardware-derived key was just an example, of course it should use many other unique things from the Windows registry. –  Jan 21 '15 at 16:12
  • @AndréDaniel That's fair. Just be aware that there's widely varying skillsets here, and not everyone knows about entropy or what high entropy is. The result is that many people would simply use the example given as a valid solution. – Steve Sether Jan 21 '15 at 16:30
  • @AndréDaniel most users won't change their credentials even when they're told to. Even when a utility requires users to change their credentials the utility usually has to disallow previous passwords because otherwise users will just revert to previous credentials. Any solution that relies on users changing their credentials is likely not a real solution. – Rick Jan 21 '15 at 18:31
  • The solution is to create and store an access token, which can be easily deauthorized and a new one created without the possibility of a compromised password. this is especially important as passwords are usually shared across many utilities so a compromised password is *much* worse than a compromised access token. You should address this in your answer as it is a major security flaw in your proposed solution. – Rick Jan 21 '15 at 18:36
  • @AndréDaniel The idea is to only send the encrypted part, the 'key' would be on the server. You would only send a session cookie and the data to decrypt. The only thing that the app has is the encrypted password and the cookie identifier received from the server. Nothing else. All the device-specific data can be sent over HTTPS to be used to add some uniqueness to the encrypted data. If you want, you can hash it with a nice salt and store on the app too. – Ismael Miguel Jan 21 '15 at 18:46
-1

This is what i had in mind as i already have built an application like this that works like a charm.

As you are already using TCP you could encrypt all the data that you are sending and decrypt them inside the application.

  1. User logs-in and the data that he has entered the first time is sent encrypted to the server.

  2. Server reads the encrypted data and checks if the login is correct and sends back a reply to the client.

  3. Client reads the data and checks if there is a login success.

  4. Token is stored inside the application so the user wont need to enter the data again.

  5. Each time the user launches the application, the application then first check the login token,and then auto-login while the startup screen of the application is loaded.

Encrypt all incoming and outgoing data if you are planning to make a messaging application, or if it is a web related application then just encrypt the important parts.

Use a 3-way handshake if you would like to use a custom TCP, or use HTTPS if that is what you desire if its web related.

There is only one problem that could mess everything up and that is if the users machine is infected with a keylogger which can read all data sent from the keyboard.(ex. the first time he has to use his login credentials)

I hope this has helped you enough to lead you in the right direction.

  • 2
    You're kinda over complicating things. First there's really no need for manual AES on the client-server communication, HTTPS can already take care of that and is a lot easier to implement. –  Jan 21 '15 at 15:47
  • I agree but i just like securing things. HTTPS is not secure as we have seen in the past. – GaringoXXS Jan 21 '15 at 15:55
  • If you can sniff HTTPS without your app screaming certificate errors then you've badly configured your HTTPS client library (sadly you're not the only one and I've seen that in an app on the Android Play store). –  Jan 21 '15 at 15:56
  • Seems like you know more about myself then i do. HTTPS and TLS arent secure enough and if you did some resourch you would have known that. – GaringoXXS Jan 21 '15 at 16:14
  • 2
    But then how do you explain that everyone is happily using HTTPS and so far there aren't been much issues (other than the occasional vulnerability like Heartbleed but that gets patched in a matter of hours on anything important like a banking website) ? –  Jan 21 '15 at 16:16
  • Dont speak for everyone, YOU are happy using HTTPS and keeping things simple. There are plenty of people who have exploits and that are being used privately, such as the NSA etc. etc. The Heartbleed has been out for a long time and nobody knew except the people that discovered it and abused it. – GaringoXXS Jan 21 '15 at 16:30
  • Don't be skeptical and lets stop this argument right here. – GaringoXXS Jan 21 '15 at 16:35
  • My only problem with your suggestion is with "Credentials are stored inside the application" Why would you store the user password? – fgpr0x Jan 21 '15 at 16:45
  • You need these credentials to check the login during the loading screen, sessions are also possible but session hijacking will be a problem then later. If you dont feel good about the idea then let me think what should be a better way, i will send you a message later on when i arrive at home. If you send the data to the server encrypted anyways then you can save the credentials also, i can understand its confusing but its better. You can also re-crypt the saved credentials after each successful login or something like that to make it harder for an attacker to read it. – GaringoXXS Jan 21 '15 at 17:00
  • 2
    What you're proposing is effectively sessions that use the password as the session key... which is inherently less secure than a properly implemented session/access token. – Rick Jan 21 '15 at 18:42
  • 1
    Also trying to role your own AES is basically trying to re-implement https which as you pointed out has had security flaws in it. Your own version *will* have security flaws in it too, the only advantage would be security through obscurity. Every time a flaw has been found (by an upstanding citizen) in https, a patch goes out and it becomes more secure. Who would look for and find the security flaws in your custom system? (only the people who want to exploit it) – Rick Jan 21 '15 at 18:46