I'm trying to set a cookie so that user can be automatically logged in.
I do not want to query DB for session string when authenticating cookies (basically I need to do that whenever most of my APIs are called, I want to make it faster)
the solution I found is to set a hash in the cookie and try to decrypt it when authenticating, if decryption is successful then log user in.
I am wondering what hashing method should I use? Do I just use a constant salt in my program and hash the userName with that salt, store the hashed userName and original userName in cookie, and try to match userName with decrypted hash upon authentication?
Since I am not familiar with hashing functions, can anyone kindly provide some suggestions on how should I do it in Java?
I recommend you to use an unique token key generated for each session. For example, if a client once logged in from a computer, this token will be valid until the password is changed. Expiring a cookie is not completely secure...
You can also use session variable for a simple authentication. Once you set a session variable for an user, every time this user sends a request with this session id; your session variable will be reached for just this session id. Most of the platforms can also use DB for storing these variables for you.
Two approaches:
1) Create your own authentication framework. In this case I recommend to 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). For encryption please use AES-256 encryption with BouncyCastle:
256bit AES/CBC/PKCS5Padding with Bouncy Castle
If your framework success to decrypt the cookie – the user is authenticated. If your framework cannot decrypt the cookie or the user is not exist - the user is not authenticated.
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
Best regards,
Michael
I don't come from Java background, but your hash key should never be something exposed.
For example:- In your case UserName is key and one of the fellow developers who knows what mechanism you are using can break it down because name is something very common and known.
Don't know what the best way is but I have used UserID(GUID) which is not visible in UI.
Related
In my project there's a requirement to invalidate all jwt tokens of a user when the user changes his password. I was thinking of giving each user a different signing key, and simply reset the key when password is changed. Then I googled around and found Redis is a good place to store those per-user keys. Everything seems to work just fine.
But there one thing I cannot get my head around. Since it has to hit Redis once per request, is it any different than issuing the user an opaque token instead of JWT, and store the token -> JWT payload mapping in Redis?Isn't that defeats the purpose of using JWT?
To invalidate tokens you need to revoke them. OAuth spec also does not require getting secret key from remote server every time you need to validate JWT (as you said it kind of defeats the purpose). The key can be stored locally at resource site.
You have two options here:
1) Introspect the JWT token from resource side against OAuth server every time it validates it. Seems like overkill to me. The best approach is to give short expiration time to JWT token and let the already issued tokens to just expire.
2) Have the resource store the secret key locally and when it fails to validate go and get the key and re-validate it again.
From the point of view of invalidating the token, there's no particular need to store the JWT in Redis - anything that you can check and later invalidate should do the trick.
That said, presumably you're using a JWT for other reasons. For example, it's what the AuthN/Identity service provides. Or perhaps you use it to store claims or other metadata that you validate as part of the AuthN/AuthZ logic. In that case, since it's handy, storing the JWT seems very reasonable.
There is a common requirement of storing user credentials securely (user id / user password) in the App and use them automatically next time the App starts, but I'm not being able to figure out how to do this without user interaction.
Using JSON Store I need a password to encrypt the information, so if I store user credentials in the JSON Store I will need to ask to the user for the password used to encrypt the information.
A solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
As explained in the comments this is a really bad idea.
Is there any solution to store user credentials securely and recover them without user interaction?
You can use the Keychain API on iOS. Android doesn't seem to have an equivalent API.
The most complete solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
I would strongly advise against doing that, if you store the encryption key (the user id) in plain text, then the attacker can simply use that to get to the password.
Update (Aug 27, 2014)
You should consider:
Hashing - You could hash values you want to protect. These are one-way functions, so you can't get the password back once you hash it. However, you can verify that the user provided the correct password. For example: First login you store( hash(password) ) then on next logins you compare if hash(password_provided) == stored_password_hash. If it matches, the user provided the same password. You should also use a salt.
You could give the user the ability set a pin using some library like ABPadLockScreen (you could probably find or implement something similar for Android too). You can then use the pin as the PBKDF2 input to generate an encryption key (JSONStore will do this for you when you pass the pin as the password). I would advise in favor of letting users only try a small amount of incorrect pin numbers, especially if the pin is only numeric and short, that way they can't easily guess the pin by trying various combinations. The idea here is that a pin will be easier to remember and type than their password.
FYI - There's a Stack Exchange site similar to StackOverflow but for security questions here.
I'm currently making some research on the WSSE protocol to secure my api.
I've understood the basis and it is clear in my head.
However I face to a problem.
Let's say I want to generate a ONE-time Digest, I've to concatenate the timestamp, the nonce and the secret password.
However, on the server side, I don't have the clear password stored in database, so I'm unable to check for the digest.
Switching to clear password is not an option.
I can't either provide to the client-side the algorithm used to hash password, because they use salt, and the salt is not available to the client.
The only solution I can think about is to don't hash the Digest, just concatenate the data and base64 them.
That way I'll be able to encode the user password to check for its validity.
As password is transmited in plain text it may not be secure, but what if I force HTTPS to authenticate?
Will it be safe?
As password is transmited in plain text it may not be secure, but what if I force HTTPS to authenticate?
Will it be safe?
Yes, and within normal limits, it is the only way to get it secured.
Just send the full password, but send it over a well secured TLS connection. You can use a secure key derivation function such as brypt or PBKDF2 and input the stored random salt (one per user) and password to retrieve the "hash", which can then be checked to the one stored in the database.
Note that you don't need to send a time stamp from the client. It is of course a good idea to log & limit the number of authentication attempts though. You cannot use a time stamp as input to a hash, the outcome would be different each time the time stamp changes.
I am making a program like yelp. Some people have some accounts. So I got to send the password to the web.
Should I encrypt the password before sending it?
After that what would be the standard password policy others used?
Should the encrypted password be the one stored on the mySQL serve? In other word, there is absolutely no need for decryption?
Basically it's like What encryption procedure I must use to send encrypted 'email' and 'password' values over the HTTP protocoll? but for objective-c
After the user logged in, my program need to tell the server that the user is authenticated already. Does my program need to keep sending password?
There are more than one architecture you can implement, and you have to choose considering many factors, like performance, how many users, server architecture...
Basically, you must use https and not http, store hashed password (MD5, SHA, ecc.) and always check if hashed password is equal to stored hashed password.
You can implement also a "session" using token (you have to create a kind of API server side and then use it on client side) or pass username and password in each call to web service (web service must verify credentials every time is called).
Another "fast" (it's not so fast anyway) solution is to implement (both server-client) a standard protocol like (it's my favorite) oAuth 2. It's used by twitter and Facebook, you can learn more here: http://oauth.net/2/
You might be looking for Base64 encoding:
http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html
What would be the most secure method of using cookies to authenticate users in a classic ASP website?
I don't want to use the ASP Session object as the session cookie times out after a while, and I'd like the user to be able to keep their login to the website active between separate browser runnings.
However, I don't want to just create a cookie containing their user ID as that could be easily forged - so what are my options here? I guess some sort of encryption but I don't really know what the standard methods of doing this is.
Your options here are pretty much limited.
Get your users to log back in again; best security approach.
This obviously applies much wider than just ASP.
The best way would be to hash the password... you should be doing this in any case where you store it in database.
The hash is a cryptographic function - when you run a string through it (eg password) you get out a long code. If the input is the same, the output is always the same.
But (this is the important bit) its mathematically virtually impossible to reverse the process - to start with the hashed value and work out the password, other than brute force (someone hashes dictionary, or random strings and looks for output that matches the hash they have).
So when the user sets up account, they put in their desired password, but you hash this, and store that. Similarly in the cookie, after they login you store the hash, not the password, and this has is compared with the hash in the db.
The downside is you can't send a password reminder since you don't know the password - to you'd have to send a password reset link and have a system to do that.
If you're really paranoid you might double hash, eg when they login the password is hashed once and stored in cookie. Its then hashed again and compared with the password in db (which is also double-hashed).
Don't Do It
Maintaining a user login quote "...between separate browser runnings" is not secure. IMHO, when you close the browser a previous login should be gone. Suppose your visitor was using a community pc at a coffee shop.
If you maintain this login the potential for the next community user to open the browser, navigate to your website and "poof" they are automatically logged in as the previous user.