iOS: Encrypt Login Password to send to API - ios

I need to encrypt an NSString before sending to a WebAPI.
What are the best practices for this? I've been looking at different articles but haven't found what I'm looking for.
The whole hash/salt with date thing seems like the best approach as of this writing.
ANyone know how to do this in iOS?
Then, do I just store it in the DB as varchar(50)?
And for subsequent logins just do a text compare?
Thanks all.

Encrypt and authenticate the connection to the server with HTTPS. This counteracts eavesdropping and MITM attacks. Be sure to verify server certificates on the client side.
On the server, hash the password with a randomly generated salt.
Store the hash and the salt in a database. Yes, you can use something like a text or varchar(50) to store the hash and salt.
This has been covered in a few other questions before: see Best way to store password in database

Related

Devise with previous encryption

I'm currently developing a new application, I had made one in the past and I had done all the users manually but now I'm looking to use the best way possible to implement my users. I had thought in the past of using the gem but because of time reasons I didn't have the time to implement it, now that I'm starting fresh I wanted to start using the gem to optimize and use what the gem has to offer, since I really liked it.
Anyway, my issue is, for security reasons since I will be passing parameters through mobile I will be encrypting the password to pass it to my application, and then with that encrypted password I will encrypt it once again to compare it to the encrypted password, so what I wanted was a way to encrypt the password before devise encrypts it, that way when the mobile app passes the encrypted password it will match to the previous encryption.
I tried a before_save on the Model, without luck, it just saved the encrypted_password empty, I'm not sure why.
tl;dr I need to encrypt before the gem, tried to do it with before_save/before_create on the model but it didn't work, anyone knows any way to do it?
Consider the following fact: If you encrypt the password before sending it with a method which allows you to decrypt it at server level, then this means your method is not one-way and the password sent may be decrypted by other person using a middle-man attack. Then you are not safe at all.
It is much better to use HTTPS/SSL to send this kind of sensitive data. It encrypts all you send at transport level and does this in a way better than anything you can implement by yourself, no offense meant.

What is the standard procedure used for login-systems in iOS-apps?

I am creating an app and a website for a project I've got going, but I'm not sure what I should do about login. This is not a "I'm a noob and I want an app with login"-question. I am somewhat experienced with both web-, database- and app-development, but I've never actually touched the subject of security before other than by application templates.
What I'm imagining is a 'simple' login-system like Skype, Facebook, NetFlix, really any app that you are able to log in to, which also has a website to log in to.
A part of my question is towards the security of the process. My initial thought is that a password in clean text should never be sent over internet, which makes me believe that the passwords should be hashed/encrypted on the phone, as well on the website, when logging in. I've done some small-time hashing/encrypting before, but just by using sha1 and md5 to "convert" the text. What's the proper way to do this? With my current knowledge, I assume that if I'm using md5 to encrypt a password, anyone could decrypt it with md5 too, but that I could use a SALT(?) or some form for altering key. Is that how the "big boys" are doing it, or is there a secret passage I don't know of?
Now onto the real question.. How should I store a login securely?
What I've tried: When making a "test-project" in Xcode for this, I simply created a class User with a field for username. When "logging in" by entering a username and password, I simply sent a POST-method HTTP-request to my .php-page, which simply performed a SELECT * FROM User WHERE Username = '$_POST['username']' AND Password = '$_POST['password']'; If the database returned one row, then the password was correct, and the page could print out the user in JSON or whatever. When the device got the successful login, I converted the user-object in the app, now containing the username (and potentially UserID, E-mail, Address etc.) to NSData*, and using NSKeyedArchiver and NSKeyedUnarchiver to save and load the user, never to authenticate again. If the user clicks "Log out", I wipe this 'archive'. This works, but I sense that it's not a particularly secure way of doing it. If so, why exactly is that?
(Our back-end is currently Google's App Engine(java), which has support for OAuth. Some are recommending this, but we can't find any proper documentation that makes sense for our plan with custom users)
Password Transmission
The easy way to secure this is to just send passwords over SSL. If you set up an SSL certificate and do all your authentication over https, all the back-and-forth communication is encrypted by the transport layer. Note - md5 is not an encryption algorithm, it's a weak hashing algorithm - don't use it for security.
Storing Logins
Your passwords should be stored in the database as a salted hash (random salt, with a collision-resistant hash function such as SHA256). Don't store the plaintext version of the password anywhere. If you're using PHP on the server side, you can use the new password_hash() function or crypt() to generate and compare your salted hashes.
If you're communicating securely over SSL, you should be able to just use the session capabilities of your web server to keep track of logins (e.g., $_SESSION['user_id'] = ...).
If you want to securely store your username/email/address, or anything else for that matter, the built-in keychain is the only Apple-happy way to go.
Have a look at SSKeychain (or PDKeychain or UICKeychain) and extend it to include each property you'd like to store. Generally it's used to store username and password combinations, but can be extended to store arbitrary data safely.
As for passing secure data to your server, do it over HTTPS.
I can provide examples if you'd like.
Another option is to add some sort of OAuth or XAuth login process.
That way, you are not storing any passwords, but only so called "Tokens". The tokens expire, and can be revoked.
Not storing the username and password at all is the best way to secure them.
Alex

How to securely store user passwords for an external application?

I'm building an application with Rails and will be pulling timesheets from Harvest, a timetracking app. I'm using an API wrapper called harvested. To be able to interface with their API, I need to provide a subdomain, username and password.
Right now, I'm just storing the passwords as plain strings and have not done any encryption. Would like to encrypt them before storing in the DB. If I encrypt the passwords before storing, can I still use the encrypted password for authenticating with the Harvester API?
OAuth exists for this very reason. Storing plaintext is obviously a bad idea, but storing something encrypted that you then decrypt is ALSO a bad idea.
Modern password flows use one-way encryption: encrypting the password and then comparing it an already encrypted value in the database. This allows use of algorithms that can encrypt easily but are essentially impossible to decrypt. Using an algorithm that allows your application to easily decrypt database fields will also allow an attacker to do the same.
With a one-way flow (encryption only), even if a user gets ahold of your encrypted passwords, they are unusable since anything entered in the password box will be passed through the encryption again before testing for validity.
TL;DR
Use OAuth as someone else pointed out: https://github.com/harvesthq/api/blob/master/Authentication/OAuth%202.0.md

Encrypting (not hashing) and storing user passwords on a rails server, using devise cookies

Got a bit of an issue where I am required to maintain a secure connection with one server that proxies out requests to another, over basic authentication. However I can't be allowed to gain access to the password for the users who want to access the other server. Can anyone suggest a way to store the password (having been given it once) securely in say the session variable, encrypted by a key that only the client holds until the point when it's needed?
After a time it can expire, ie, you could give the username and password and half an hour would be an acceptable time to keep the credentials in case the user wanted to access the site again.
I've rewritten this a few times after producing pure waffle, sincerely sorry if the editing didn't make much difference.
If your server is going to be handling the password in plaintext (to talk to the other server with Basic auth), you're going to gain access to the password. Perhaps you want to avoid storing the password in plaintext?
Send the password in plain text to the server, which then encrypts it, stores the encrypted version and adds a cookie to the client with the key. Then any future requests provide the key to the server.
If you're looking for an encryption library, Recommended two-way encryption gems for Ruby?

Rails database - how to store encrypted data using the user's password?

I have a database that will be holding sensitive data, so it should be encrypted in the database. Basically the sensitive data are credentials to another web site. So I want to encrypt them with the users password + salt.
To decrypt the credentials one would need the password.
I see two ways:
On login, I could decrypt the credentials, and then store them in the session? Is that safe?
OR
Harder on the user would be to ask again for the password before decrypting the stored passwords/ids?
We don't want to have any ability to use the stored credentials ourselves.
I highly recommend "Security on Rails" for this. It's a tricky topic, so you'll need to spend some time reading up in order to get it right. They cover exactly this topic, including how to salt the encrypted data, unit test to make sure it is encrypted, and more.
Their sample code shows how to add class methods to ActiveRecord::Base so that you can make any database column encrypted in one line of code. Definitely an idiomatic Rails approach.
It's an awesome read - the unit tests blew me away, so seriously ... go get it.
By the way, when you said
We don't want to have any ability to
use the stored credentials ourselves.
you realize that because your code receives the unencrypted data from the user's browser, you do have access to the data in memory before it is encrypted on disk, or when it is unencrypted when the user wants to use that data later. And bad people could get access to that data if they root your box, sneak something into a Ruby eval(), etc.
Encrypting the data does help a lot, though. SQL injection attacks can't get the decrypted data, for example.

Resources