To manage the secret- I am planning to use ENVCONSUL.
As part of the envconsul setup, I have to pass VAULT_TOKEN. Now during deployment, I can pass the VAULT_TOKEN as a parameter(as suggested by hashicorp).
However- how can I keep accessing this VAULT_TOKEN securely for normal app stop/start? Because at that time, there won't be any other tool to pass that environment variable.
There are a number of ways to securely store the token:
If you use a password manager (bitwarden, lastpass, dashlane, etc) then you could store it there
write it on a piece of paper and keep that safe
don't keep the token at all - instead configure another authentication engine, and log in with that each time you need a token
store it in an encrypted file on your hard disk. In this case you still have to securely store the encryption key or password somewhere (might be more memorable though)
memorise the token (only joking)
Related
I was going through the OpenID Connect Dynamic Client Registration specification. Section 4.3 lists the response for a client read request in which the client secret is displayed in plain text.
While obviously the secret needs to be returned in plain text when registering the client, having to return it in plain text on read requests later implies that the secret value itself needs to be stored (likely encrypted) instead of the salted hash of the client secret.
Since client id and secret are basically the same as username/password, I'm wondering why is the spec requiring to return a secret in plain text in this response, basically going against best practices in password storage?
Passwords are a special kind of secret which are often memorized by users. Since users often re-use passwords, it is important not only to hash the passwords (to protect against reversing it), but also to salt it (to prevent rainbow tables from being used). Secrets such as the client_secret are usually generated from a random source and used only once. Someone who gains access from the database can therefore steal the secret, and impersonate the client, but it won't have value elsewhere.
The client secret needs to be available when a client is configured. If you are for example provisioning multiple instances of a service, you might want to dynamically obtain the client configuration including the secret when you are deploying the application.
To recap, there is a different risk model, the secret is assumed to be random and used only once, whereas passwords are often reused. The secret is supposed to contain enough entropy to protect against a brute force attack, passwords are often shorter or from a dictionary.
There is also a use case for making the secret available many times without needing to change already provisioned clients.
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
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
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?
I'm trying to figure out a way to store user-generated text securely in a database (so that only the user is the one who can access his/her stored text). I could have Rails encrypt and decrypt the user's text entries using the user's password as the key, but if the user ever forgot their password there would be no way to ever decrypt their previous content/text (since the Rails app uses BCrypt to store only a hash of the password).
Does anyone know how that could be done? It looks like Dropbox does something like it: "All files stored on Dropbox servers are encrypted (AES-256) and are inaccessible without your account password." (http://www.dropbox.com/help/27) Yet they allow you to reset your password and I'm assuming they don't store your plain text password anywhere.
What am I missing? Any suggestions would be greatly appreciated. Thanks!
Logic dictates that are only two options:
You encrypt using a key known to the server (user's key hash or some other identifier). Intruders can potentially read all the encrypted data, but the user can never lose the encryption token because it is on your server.
You encrypt the data using a key known to the user only (e.g. his password). Then intruders will not be able to read encrypted data, but if the user loses his key, the data is as good as a pile of random bits.
It's clear that Dropbox has chosen (1) from the fact that they allow to reset your password.
Build on Gintautas' Option 1 with a two-prong encryption plan:
Apply option 1, with a key that is known to the server, and
Store the database on disk in an encrypted format with a key that is known only to the server. E.g., in an encrypted volume. When the server starts up, the key must be manually entered in order to access the database.
This "static security" provided by part 2 protects against an intruder in the system gaining access to the database files. Maybe not 100% the exact security you're after, but getting closer.