I am trying to authenticate users for my Flutter app with hashed credentials. That is I'm hashing them before requesting auth with .login(). Problem is that the hashing packages I'm looking at using both have a function for checking the plain text password against the stored hash. This works fine for offline auth, however when sending hashed credentials to Parse auth gives invalid username/password error of course, because the algorithm changes after app restart.
The local side of things is pretty easy, now I'm caught wondering if it's secure to send users credentials in plain text through https Parse request?
I can't see a way to verify equality of hashing just entered credentials with parse because the hash is always different on app restart. Do I have any other option here?
Can someone give me some guidance here please?
Related
For token based authentication for any service, first we have to send username/password in the request. Doesn't this cause security issue? How can we overcome this security issue of passing username/password?
The initial request which contains the username and password is no more or less secure than subsequent requests which would instead be bearing some sort of token. The solution to this problem, really to sending any type of information across the network, is to use two way SSL/HTTPS. With HTTPS, information being sent gets encrypted on the client machine, and then (in theory) only the server would be able to read what is contained. So, sending the plain text username and password might seem insecure, but if using HTTPS, then in fact it is secure.
I want to do the following
User signs up to IOS app and provides username and password
Make a server call and store password in server database
When user logs in in the future, retrieve that password and check against the password that the user entered.
How can I do this in the most secure way possible? I was thinking of encrypting the password when storing in the db. When the user logsin, use the same encryption algorithm and compare against the db encrypted password.
NEVER ever store user credentials in encrypted (reversible) form. Currently best known way for checking user credentials is slow salted hash
for what and why please read https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
However, don’t try to invent your own algorithm for repeated hashing.
Choose one of these three well-known ones: PBKDF2, bcrypt or scrypt.
As already commented you may outsource the user authentication to some reliable service (google, fb, aws cognito, ibm appid,...)
Have you tried looking into databases? I know that Firebase has an authentication component of their database for ios development, and you might want to try to look into it or other databases. Check out firebase at: https://firebase.google.com/
In my app, the user should be able to login regardless whether they are online or offline, so is it possible to add offline authentication capabilities to my app, because I believe the package google_sign_in only does online authentication.
If all you're doing is asking for an email & password, that's fairly simple to check against and you can do it without having to delve into native code.
However, you'll also want to store the password information securely so that will require a little more work.
During registration:
Ask for username and password, then confirm password
Hash password securely (use an algorithm meant for password hashing like PBKDF2, SCrypt, or Argon2, and use a salt. There'a ton of stuff out there on the internet why this is important). There's a plugin for this: password.
Store this hash & the username as securely as possible - flutter_secure_storage seems a good a bet as any although only supports android 4.3+.
Use the generated encryption key to encrypt any data you need saved securely (maybe the encrypt package could help but I'm not 100% sure how complete or secure it is).
If you instead want your user to log into a server the first time and save the password as well, this should be more or less the same process except that you verify that the server accepts the password before/after hashing it.
During login:
Ask for username and password (or hopefully just password or you'll annoy the crap out of your users =D)
Retrieve previously stored password hash + salt
Verify against previously stored hash + salt
Use generated encryption key to decrypt data etc.
A few other things... make sure that the password entry doesn't support autocomplete or the user's keyboard might save their password. If you have a button to show the password you might want to think about blocking screenshots somehow while it's being shown (that's native though). And never, ever store the password in plain text! Using a hash means that at least if an attacker gets in, they won't be able to see the actual password.
Note that while this should work and should be at least moderately secure, don't treat it as a 100% secure solution. You should always get an expert opinion on how to implement your security as opposed to a stranger on SO =P.
There's also a bug open against the flutter google auth plugin about this so it might get resolved at some point that way.
And there is also the local_auth plugin which supports TouchId/FaceId on iOS and fingerprints on android - however, it will only work on android 6+ and with devices that have a fingerprint reader so you may need to have the username/password fallback anyways.
I'd be happy to answer any questions you have about this.
I am developing an app which uses several API services, the API requires that I provide username and password for API transactions, unfortunately no API token :-( in-order to automate I need to store username passwords somewhere, preferably database, I cannot use hashing because I need to send the username/password to authenticate and process API request, hence I am wondering how to go about it.
If I use Zend\Crypt to encrypt and store the password in database and decrypt whenever required, would this be enough for security? is there something else I must consider?
Looking for pointers.
PS: I am using ZendFramework2 with Doctrine/MySQL for the app.
Usually you would use a token mechanism (like OAuth). If that's not possible, one would use TLS/SSL client authentication.
However, if you rely on plain passwords (on the application-level, I still guess the username/password tupel is transmitted over a secure connection!) and you want to store them encrypted, you have to think of a meaningful mechanism to get an encryption key for your scenario. Just generating an encryption key and storing it on the same machine in plain does not provide more security.
Without more information on your scenario it is hard to make a suitable suggestion.
I am developing a web service and I need to send a username and password to the service in a GET method. Is it OK to send this information in the uri as long as it's going over a secure channel like ssl? In other words, can I have a uri that looks like /users/{username}/{cleartext_password}?
Edit: Sorry, I think I was unclear. The web service is essentially just a database of usernames and hashed passwords. Imagine a desktop application that keeps usernames and passwords in a remote database. The end user types their username and password into the application and the application accesses the web service to authenticate the user.
So, the application will need to send an end user's username and plaintext password to the service. The service will take the username and password and check that the username and the hash of the password match the username and hashed password in the database. The application itself will have to authenticate before it can access the service, but I am just wondering what is the best way to send the end user's username and password to the service for authenticating the end user. I don't to use a POST method because I am simply authenticating and therefore not changing the state of the server. Sorry for the confusion.
Do this.
Send a "key" and a "digest".
The "key" is equivalent to a username.
The "digest" is a SHA1 (or MD5) hash of the key, the URI and a "shared secret" or password.
When the server gets this, it computes it's own version of the digest, based on key, URI being requested and the "shared secret" or password. Failure to match digests is a 401 error response.
If it's going over a secure channel, there's no problem sending the username and password as cleartext. I'd just recommend against ever sending them as cleartext through an insecure channel and against sending them repeatedly for each request.
What you could do is first authenticate to the web service (send the username and password via ssl as cleartext) and get a token from the server that it will recognize. Then send that token with each subsequent request.
Generally speaking this is not a good idea... This data will be present in a number of log files, consequently the data could be visible to people who should not see it. At the very least you should hash or encrypt it before sending it if you can.
Here is a related discussion for a little more detail... Is an HTTPS query string secure?
SSL does encrypt the URI, but definitely take a look at some alternatives.
HTTP Basic Auth is nice and simple, and well supported by browsers, webservers, etc
It also won't end up in log files to the same degree as URIs
NB: It's just some plain-text HTTP Headers, so definitiely NOT recommended for non-SSL apps.
http://en.wikipedia.org/wiki/Basic_access_authentication