SSL - Hash Password or Not - ios

I am very new to authentication/ssl especially combined with ios. My question is, if I am sending a username and password to lets say https://server.com/login.php do I need to hash my passwords in the iOS client or can I post the text of password then hash them before they are stored in the DB?

Hash them beforehand for sure!
Sure you're using https, but it's a best practice to never send sensitive information in plain text if you can help it.

Sending an hash or the cleartext password is essentially the same issue.
If an attacker can capture data from the connection between client and server, he can later authenticates himself impersonating the client by sending either the hash or the cleartext password to the server.
The key point is to use HTTPS, wich encrypt communication between client and server, so that an attacker can not intercept the data (hash or password) the client are sending to the service.
That said, hashing the password is good practice for the client so that no one will know the real user password (even if the client stores the hash in memory for usability, you should never store cleartext passwords anywhere).

Related

URLSession | Authentication Challenge Response | NTLM

I am aware of How to Respond to an Authentication Challengelike we have NTLM Authentication as there are 3 options.
Provide authentication credentials.
Attempt to continue without credentials.
Cancel the authentication request.
But just want to know the thoughts here, when we go with the first option Provide authentication credentials we pass the username and password URLCredential is there any possibility of leakage of credentials, is it secure to pass the credentials, what is happening behind the screens? how Apple network API sending the credentials to the server?
Yes, we can set the policies like server domain, failure count etc. but from the security point of view is it safe? from Man in Middle Attack (MIMA) or anything else?
Maybe the way I have posted my question is not clear but I was looking more from the Application credential security point of view with NTLM Authentication and after lots of Google, I have found, how’s NTLM works and it’s pretty interesting to see that client don’t share the password with the server. here are the steps as follow.
The client makes the request to the server.
The server needs to validate the user because there is no identity so server generates 16 bytes random number called as the challenge and sends it to the client.
Client hash this challenge with the user’s password and return it back to the server that is called the response it also includes username as plain text and challenge sent to the client.
The server sends everything to the domain controller and it uses the username to retrieve the hash of the user’s password from security account manager database and hash the challenge.
Domain controller shares the response back to the server if they are identical then authentication is successful otherwise a failure.
So the interesting part is here that Network API doesn’t share the password with the server it means it very secure.
I hope it will help others, For More.
There are multiple types of challenges, and the answer to your question depends on what type of challenge you're talking about. Each challenge has a protection space, which basically tells what type of challenge you're responding to.
To answer your question for the most common protection spaces:
Basic password-based authentication (NSURLAuthenticationMethodHTTPBasic): The credential you pass is sent in cleartext to the server (HTTP) or encrypted by the session key (HTTPS).
Digest authentication (NSURLAuthenticationMethodHTTPDigest): The credential you pass is cryptographically hashed with a nonce provided by the server, and only the resulting hashed token gets sent over the network.
NTLM authentication (NSURLAuthenticationMethodNTLM): The credential you pass is cryptographically hashed with a nonce sent by the server, and only the resulting hashed token gets sent over the network.
Client Certificate authentication (NSURLAuthenticationMethodClientCertificate): The certificate is sent to the server, but not the private key data. The client uses the private key to sign the prior TLS handshake data as a means of letting the server verify that the client really does have the private key associated with that cert.
Server certificate validation (NSURLAuthenticationMethodServerTrust): If you pass a certificate obtained from the server, you MUST validate it first, or else you effectively reduce the level of security to that of HTTP (i.e. any server can send any cert and you'll be saying to trust that cert when talking to the server).
The list above covers the most common protection spaces. Kerberos is its own animal, and I don't know anything at all about how that works. And there's also the "Form" protection space, which is just a placeholder for custom authentication that you can use in various parts of your app's code, but is not actually supported in any meaningful way.
It is worth noting that Basic, Digest, and NTLM authentication provide no protection against man-in-the-middle attacks if the attacker can alter data in transit, because the authentication token provided does not depend on the rest of the request in any way. Thus, these are really suitable only for use over an encrypted channel (HTTPS).

How to throw facebook token to own server securely?

I'm developing iOS app(Swift) using 3rd party(facebook) authentication. I encountered a question which is how I can throw the access token from facebook to my own server.
I've been writing something like below..
Alamofire.request(.POST, "https://example.com/user/fb", access_token: facebook_access_token)
but I'm not sure this is safe enough.
Not only that, when I implement email/password login as well, I've been writing something like below..
var user = [email: "ex#mple.com", pass: "password"]
Alamofire.request(.POST, "https://example.com/user/", user: user)
Are those safe enough? Or if there're best practices please let me know.
Thanks!
Sending your credentials via SSL prevents others from reading the values in the middle. So, it's theoretically secure. ie: It goes through the security provided by the transport layer.
However, it's not the recommended approach to send plaintext passwords to the server. The correct way is to hash the password at each client, then send the hash value to the server. At the server, you should compare whether the hashes match. You might need to do some changes to your server logic. But, in the long run, it should be worth.
I assume you are asking whether its safe to send it over the network. If you are using SSL encrypted URL and pinning the SSL to your app then yes it is. Here is blog post explaining how to do SSL pinning on IOS
https://possiblemobile.com/2013/03/ssl-pinning-for-increased-app-security/

Storing encrypted version of user's email password on my app's server

I'm working on an iOS app where I need to store user's credentials for a 3rd party service on my server. (For example, storing IMAP login/password so that when they sign into my app it fetches from their IMAP server, so my server doesn't store their email)
I am not considering OAuth since not every email service provides OAuth. To do this I was thinking about the following option:
User enters username/password to sign into MyApp (MyApp server implements standard security measures, meaning it stores hashed version of the password and not the raw password, so MyApp server does not know what a user's password is)
Once signed into MyApp, MyApp stores the raw password into local keychain.
User 'connects' their 3rd party email account by signing into the 3rd party email account.
When the 3rd party email account successfully signs in, MyApp encrypts the email's password using the MyApp password (which is stored in keychain from step 2)
The encrypted password is stored on MyApp's server as "emailPassword"
From then on, whenever user signs into MyApp, MyApp fetches the encrypted "emailPassword" from MyApp's server and decrypts it back to its original form using the MyApp password stored locally on the user's keychain (which was used to encrypt in step 4).
Using the raw password decrypted from step 6 MyApp fetches emails from the 3rd party email server.
I am new to encryption so not sure if this is a safe (or even possible) option. Could anyone help? Thank you.
[UPDATED] Updated to clarify concepts and changed "encoded" to "encrypted"
You should rather say "encrypt", not "encode". Encoding is a mechanism which translates data using some set of fixed rules (algorithm). Base64 is an encoding, so is urlencoding. Encoding doesn't provide ANY security.
Encryption, however translates cleartext to ciphertext using an algorithm that uses crypto keys. Without knowledge of the key, the reversion of the ciphertext is very hard. (never impossible)
Okay, regarding your example:
It is implementable, but even though there are some attacking chances.
At some point in runtime, MyApp knows the cleartext password. At the time it is decrypted. The plaintext password then lies in RAM and could possibly read out by malicious software with respective permissions (root malware e.g.)
Also you need to make sure to use suitable algorithms in the right mode. AES-256 in CBC is more secure than in ECB mode. Then you also have to think of how to convert the password into a crypto key. Would not be too secure if you just used the password. Then you should also use a trustworthy library, no library from an unknown guy or so
Well, these are just some thoughts. You should get a little background knowledge before struggling with encryption. There are many options and you should really know, what you do.

Encrypt json data with secret key on IOS and decrypt it with node js

I need to protect my API for CSRF on post and put requests.
To do that, I think the mobile device (example iOS) need to send to the API server (node.js) a token. This token must be encrypted and contain a JSON data that will be decrypted server side.
To decrypt the data, the mobile device use the same secret key that the sever know.
For example : {_csrf: 123456789} will be decrypted from the token sent via the mobile device and checked by the API if it match.
Is it the right way ? If not what is the right way ?
How I can encrypt a Jon data on iOS and decrypt it on node.js ? (JWT Token does not have library for iOS)
Can you provide me a example code to encrypt data on iOS et decrypt on node.js ?
Just use https, it encrypts everything, even any query string.
The content is encrypted with a random symmetric key and that key is encrypted with a asymmetric key from the certificate. Additionally the symmetric key has a short lifetime. Additionally you do not have to implements and encryption routines.
Also note that iOS9 will by default require https to be used for all connections, any http connections will need to be white-listed in the plist.
If you do your own encryption you immediately have a problem sharing the encryption key between the device and the server. This is not an easy problem to solve.
When accessing the API from a browser page, to protect against CSRF, you can send a token in HTTP headers, for example, X-CSRF-Token, or, use a cookie.
For example, have your server send the CSRF token in an HTTP response using the X-CSRF-Token header. You can have your page send it back in the JSON on the POST or PUT. Or have your page read it from the cookie and put it into the JSON.
(HTTPS from the browser will not protect against CSRF, since any script on any other site running in the same browser can POST to your HTTPS server freely. Your page needs to have a token that no other page in the same browser has access to.)

Does iOS have a unique device ID that I could use to salt a password hash?

I have a multi-user iOS application that needs to communicate with a mysql database. I'm using php to submit queries and return information in formatted in json. Will I need to hash the password in iOS as well as on the server side? Will sending it via https be enough security?
Using HTTPS to send a password and hashing server side is enough. The only advantage of prehashing client side, is the reduced cpu power needed on server side.
The prehashed password actually becomes the new password, so if an attacker could eavesdrop the communication, he would see the prehashed password and could send it to the server as well.

Resources