I am building a swift app and has user account. I need to keep their information (password) safely, I have read that using salted hash for the password is safe, but I wanted to know if it is recommended to use this and store the hashed password in my icloud kit (my dataBase)
The recommendation if you need the original should be to store passwords in the keychain. If you only need to store a hash for verification, salt it and store it as a SHA-256 HASH (and keep the salt in the keychain, possibly the hash too).
If you need to put passwords in the database on an iOS device, and for whatever reason the Keychain won't work for you, you should use SQLCipher, and have the user enter the DB password to unlock it, rather than storing the DB key anywhere. If you go this route, use a key derivation function such as PBKDF2 on the user input.
Generally, assume that any password you store is a security issue. Try not to store them yourself at all.
Related
I'm building an app that I want to have E2EE. My struggle is with the private keys. Most of what I read they say you don't store it in AWS servers because it will not be an E2EE anymore and it's a backdoor. I don't want to create a backdoor, I want the user ONLY to hold the key. However, at the same time if the user logged in from another device, they cannot retrieve their data coz the private key on the original device.
So what are some ways to let the user be able to login from another device without having a trouble retrieving the data and not putting their private key on risk!
Please consider that I'm new to this subject and I'm using cryptoKit from Apple :)
Thanks!
You can use the user’s id and password hash (for example) to encrypt the private key and store the encrypted version of it on the server.
Encrypt the private key locally using the user's id and password (or a hash of it)
Send this encrypted key to the server to store it there
Now when the user logs in from another device, the encrypted key can be retrieved and decrypted locally using the user's id and password.
Thus, it won’t be possible to decrypt and use the encrypted key without the user’s credentials. However, this also means that if the user changes their password, the encrypted key also needs to be decrypted with the old and re-encrypted with the new password.
That’s the usual approach for your requirement.
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 need to store a sensible info in a database (clients passwords). Is there a common practice? The information should be accessible by various users. Think about service company that should make maintenance of clients systems.
I'm thinking about using AES encryption. All the information is encrypted with the same main key. For every user this main key is encrypted with the user's password used as the key and stored separately. During login and authentication the main key is decrypted and saved in a session. Later the key is used to decrypt clients info. Is it a good practice?
Thanks
P.S.: Yes, I know that it's better not to use passwords, but it's not me to decide the way to access client's servers.
I've used password_hash($pwd, PASSWORD_BCRYPT) to create a hash and store in the user table. It will be used for login verification.
Since hashing is a one way function,
My question is can I use the same hash as the account verification code in the activation email send to user.
Will it compromise security since knowing the hash doesn't reveal the password.
Yes, it would compromise security because an attacker with access to the email account (either presently or at any future point in time if the email is never deleted), could run a password guessing attack on the hash.
If would be better to generate a 128-bit key using a CSPRNG, this can be emailed to the user as is. On the server-side you would want to hash this using SHA-2 for storage, because that way if your activation table data was ever exposed, an attacker could not activate accounts that do not have valid email addresses. Note that no salt is needed for automatically generated keys of this strength.
This approach is fairly simple, and mitigates the risk in sending the password hash directly.