How should I store passwords? - passwords

I have a system that needs logins, but who i'm building it for is requiring the transmission of the passwords during login to be very secure (even using SSL). So i'm using a variant of the Digest access authentication to transmit login requests. The only problem i'm having now is how to store the passwords on the database (in a secure salted hash preferably) so they can be used with the digest request, and the password at no point is in an nonhashed format, except on the clients browser for a few seconds.
So, in a nutshell, how can I store passwords securely but allow for a digest (with a different and ever changing nonce to the database's salt) to authenticate?

As I understand it, this mechanism sends something like:
hash(nonce + hash(password + salt))
So on the server, you just need to store hash(password + salt) and salt.

You may want to take a look at the source code of this Perl module; it manages *nix accounts.

Related

Is there any way to programmatically generate a CouchDB cookie?

I'm working on an app which will use CouchDB to store some data for users. But I don't want users to log into CouchDB directly.
I will have an app client (mobile/web), an app server, and the CouchDB server. The client app will authenticate to the app server, then myy ideal scenario would be for my app server to authenticate the users programmatically, then send just the 10-minute cookie to the client app.
That is, I would like the app server to request a Cookie from the CouchDB server on behalf of the user of the app client, then send only the cookie to the app client.
The app server could just POST to _session on behalf of the authenticated user, but this requires:
maintaining a list of users' passwords in the app server
using a single, known, password for all users
resetting the password to something random for each authentication request
For security reasons, #3 seems the best, but this seems like extra work, and is an extra round-trip to the DB (albeit, not an expensive one). So my question is: Is there any, as an administrator, way to generate a cookie on behalf of a user, without using the users' password at all?
This would also potentially allow me to entirely reject requests to _session except from my app server, as an added security measure.
And for the sake of completeness, I'll also mention that I've looked at these other options, and found them wanting:
Proxy Auth
The fact that the x_auth_token never expires is worrisome to me. It means a compromised token would grant forever access to the user's data. And AFAICT, the token can't even be invalidated without changing the user name or the server secret (which would in effect invalidate everyone else's auth tokens as well). But maybe I'm missing something here?
OAuth auth
This seems to just move the problem. Now rather than storing users' passwords in my server app, I have to store OAuth secrets. Plus, now my server and client code must be more complicated.
I don't follow your exact goals. You seem to imply users might have passwords ("app server authenticating the users programmatically") but you don't want the users to "ever need to know their CouchDB password". What sort of authentication do you want?
There's two (and a half) general approaches I've taken to authentication with CouchDB:
"Man-in-the-middle[ware]" approach, where I have thin middleware in front of CouchDB. This middleware forwards username/password to the "/_session" which yields a cookie or error codes based on the CouchDB _users database. The middleware copies this cookie from CouchDB onto its own HTTP response back to the client (or displays a message in case of error). Then on subsequent requests, that need database access, it forwards the cookie (now from the client request) back again to the database.
The traditional approach, where you just use CouchDB as a data store and maintain your own "user" entries/indexes. Make sure you use current best practices for password storage/handling or use a library that takes care of those details for you. The middleware connects to the database as "itself" and handles read/write permissions with its own logic based on its own session handling.
Or — sort of a hybrid approach — you can use the "/_session" API only to see if CouchDB accepts the username+password as valid. If it does, create a separate middleware-handled session for that user. (Basically you're only using CouchDB's _user database as the "password handling library" and the rest is the traditional approach where the access control is implemented all in the middleware rather than at the database.)
For real-world production stuff, I've tended to use only the latter two (or one-and-a-half given the earlier numbering…) — the first method is kind of fun, but CouchDB's lack of document-level read permissions usually means that giving users nearly-direct access to the database server is untenable in practice.
UPDATE: your question now makes it clear that you want the client app to talk directly to both servers: the app (formerly "middleware") server and the CouchDB (database) server. I'm leaving the content above because I think it's still somewhat useful and provides a bit of background/context for this update.
You are right in your suspicions that Proxy Authentication is the wrong solution: it is not intended for end-user usage, but really to replace the cookie-forwarding "trick" portion of #1 above. That is, proxy authentication is when you fully trust one party (i.e. your middleware) to provide the user information as it works on behalf of a user. But you want the users to talk to the database directly, and you cannot trust them with the X-Auth-CouchDB-Token.
I will defer to your judgement on the OAuth option. I do think it is closer to want you want but it is clear that somehow you are authenticating users against a different service and don't need to store per-user keys in CouchDB itself. The request signing required by OAuth 1.0 does mean you'd need support in your client app's HTTP library too.
I see a few options, without building a custom CouchDB plugin, that could let your app server hand out a token to authenticated users which your database server will accept:
Proxy after all! That is, hide your database server behind your app server or another lightweight custom reverse-proxy. All this middleware needs to do is check your existing client app session (cookie or other authentication header) and if it's valid, set the internal proxy auth headers that CouchDB will accept — then it forwards the rest of the request/response verbatim.
Deterministic password, per-user if it makes you feel better. Configure your app server with a secret known only to it, then set each user password to something like HMAC(username, app_server_secret). Now when you want to generate a token for a user, your app server can generate the password on a per-user basis. Note that this really isn't any more secure than just using the app_server_secret as the password for every user — CouchDB already salts and hashes each user password independently so if someone gets a hold of the database but not your app's configuration values the attacker couldn't tell the two apart. In both cases, preventing unauthorized database usage hinges entirely on keeping app_server_secret secret.
Re-implement CouchDB's current cookie generation algorithm. CouchDB's cookie algorithm (view source) is basically data = username + ':' + timestamp; base64(data + ':' + sha_mac(data, secret)). Where secret is the couch_httpd_auth.secret value plus the user's salt value. You can tell your app server the couchdb_httpd_auth/secret value and it can follow the same steps to generate a valid cookie which you provide to the client app, and CouchDB will accept it as its own. This cookie will be valid until the timestamp + the configured couch_httpd_auth/timeout. As "hacky" as it seems, this is probably the closest to what you are asking for, although you still need to set/disable the users' actual passwords somehow.
Expanding on natevw's brilliant answer. I was having similar problems, and never would have realized option 3 was possible without having stumbled across that answer.
Here is my python3 implementation for generating a cookie (uses pycouchdb to interface with couch):
def generate_couchdb_cookie(couchAddress, couchSecret, username):
timestamp = format(int(time.time()), 'X')
data = username + ":" + timestamp
server = pycouchdb.Server(couchAddress)
db = server.database("_users")
doc = db.get("org.couchdb.user:" + username)
salt = doc["salt"]
secret = couchSecret + salt
hashed = hmac.new(secret.encode(), data.encode(), hashlib.sha1).digest()
inbytes = data.encode() + ":".encode() + hashed
result = base64.urlsafe_b64encode(inbytes)
return "AuthSession=" + (result.decode("utf-8")).rstrip('=')

Store passwords accessible

I want to write a library for my media files. Since I am using a few SAMBA-shares i was wondering how I should save the passwords, since I need them to access the share. Is there any other possibility to store them than just plain text?
I am using postgresql for the data. The end-product will be a web app.
The difference to other password saving questions is, that i need to send the password to other services. That's the reason why I can't save hashes.
If you store the NT hash you should still be able to NTLM authenticate to Samba. This isn't a bulletproof solution since the NT hash is as good as the password itself to servers that accept NTLM authentication, but assuming that your Samba server is well-protected on a private network it's still an improvement. Among other things, it makes it less likely that someone stealing your password database can use the contents to compromise users' accounts on other systems where they may use the same password.

Shiro - Don't transmit password to server

I'm not much of a security expert, so I've implemented user authentication for my Client+REST API using Apache Shiro. Everything works, however I'm a bit confused about one aspect: Shiro seems to require me to transmit the user's password to the server for authentication.
I have a endpoint, /user/auth that my frontend (angular) POSTs login info to, which then creates a UsernamePasswordToken and calls Subject.login() with it, and Shiro then takes care of querying my db for the 'password' string it generates (using DefaultPasswordService.encryptPassword()) and comparing it with the password the user POSTed. This is all going to be over SSL once I put it on a public server, however it still seems strange to me to be sending the user's password to the server every login, instead of hashing it somehow.
I'd thought the default practice was to hash the password on the client side, and then send that to the server? Or does this just not matter anymore once you've got SSL? Would it be better to have the client hash the password before sending it, even when registering, so that the server would only ever store the hash? I know Shiro isn't storing the password in plaintext, so I assume its storing a hash in my database, but it could just be encrypted with something for all I know.

Why is it a bad idea to send username and password with every request between mobile app and backend api?

I've been looking at the traffic from what is supposed to be a secure iPhone app for a work related task recently, and I've noticed that the app does not use any form for session id / token when talking to the backend. Every request contains the username, password and the device id, and all traffic is sent over https. It's a restful api, so there is no state server side.
I really feel that this is a bad idea, but i cant come up with too many good arguments for why.
If you are the victim of a man in the middle attack, the attacker can in most cases find your password when you log in, as the username and password needs to be sent to the server to obtain the session id / token anyways.
A better approach might be to send username, a timestamp and hash of timestamp and password. This server then drops the request if the timestamp is x seconds old, and the cleartext password does not have to be sent over the wire.
However, most apps i've looked at (except those who use oath and so on) just send username and password in in cleartext (over https) to obtain a token. this happens every time you start the application (both username and password are stored within the app data).
As the topic says, why is it a bad idea to send username and password with every request from a mobile/web app to the backend api, if https is used?
Well, you stated it yourself. You have to store the username and password on the device itself. How secure are those credentials stored? Would a rogue application installed on the device be able to retrieve the credentials? If the rogue application is running under the same account as the valid application, it probably can. Even if you store those credentials encrypted, you'd have to store the secret on the device itself.
Also, mobile devices have a much higher likelihood of being lost/stolen, giving an attacker access to the device itself.
Another reason is that sending the username and password every time, increases the attack surface. It will give an attacker more messages with constant data to try to decrypt.
Finally, verifying passwords, when implemented correctly should be relatively slow, making it less desirable for API authentication.
Protocols like OAuth 2.0 work with access tokens that are valid a limited time and you'd have to have access to the refresh token to get a new access token. Refresh tokens can be easily revoked in case the device is lost or stolen.

User Authentication by Decryption

I'm trying to avoid DB access upon authentication to improve performance
a valid solution after lots of searching seems to be storing an encrypted string in cookie and try to decrypt it upon authentication.
Thus, I am wondering if the following is a good idea:
transmit everything via SSL (I'm lazy..)
set a global constant secret key in my program
generate a new random verification string upon registration and password change, store it in the User object
generate an encrypted verification string with verification string and secret key
store the unencrypted and encrypted verification strings in the cookie
when user tries to login, decrypt the verification string and check against the original verification string
if it is an "OK" idea, how do I actually make it work, like:
what encryption method should I use, AES-256?
how do I do this kind of encryption/decryption in Java, using Bouncycastle?
if it is not a good idea, what should I do to avoid querying DB on authentication?
thans in advance!
The problem you describe above is called “RememberMe”.
Two approaches to solve your problem:
1) Create your own authentication framework.
Upon the successful authentication put in a cookie an encrypted value of a username (I strongly not recommend to use hashing; also please do not put the user password value).
The cookie should be persistent at most for 2 weeks.
For encryption please use AES-256 encryption with BouncyCastle:
How to use Bouncy Castle lightweight API with AES and PBE
Please do not put any plain values in cookies.
If your framework success to decrypt the cookie – the user is authenticated. If your framework cannot decrypt the cookie or the cookie does not exist - the user is not authenticated.
Upon the logout please clean the cookie.
2) Please consider to use the Spring Security framework:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html
It is the great framework and solves a lot of authentication / authorization problems.
Your problem is solved by the “RememberMe” feature:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-remember-me
Please tell me if you need any additional clarifications.
Best regards,
Michael