everybody.
Say, I have a web server and a client, which connects to it for the first time. The authentication mechanism is:
1) parse the client's UsernameToken element and retrieve its username, password and
nonce.
2) evaluate a hash: SHA2 (username + password + nonce)
3) check if a Data Base contains such a hash.
Let's assume that there is such a hash. The question is, how to know that the client is already authenticated, when it connects the second time?
Searching the DB is rather expensive, so I can't do it at every connect.
Saving the clients hash in memory will increase the performance, but how long should it present in such a registry and it seem to be a huge security hole.
Session parameter? But how can it be implemented in the web-services context?
Related
Everything is in the title.
After a successfully post request to create a user, should I include the password in the response ?
Thanks.
Password goes the only one way, from user to server and never comes back. Actually after user is created, you should not posses password as plain text anymore. It should be hashed by BCrypt or other secure hashing function and stored in database.
Even though password would be hashed you should never send it to the client (browser)
Intro
The users of our web application must log in in order to use the app. Communication uses (along the XMLHttpRequest) the WebSocket API.
The questions
Is storing the user name + password in a <input type="hidden"> of a <form> and then sending their data values to a login script sufficiently safe? If not, what could we do here?
Is it possible to store an arbitrary object (say, class User {...}) in the WebSocket's Session such that I can type in the login script:
session.setAttribute("web_app_user", user)
user = (User) session.getAttribute("web_app_user")
such that it is not possible to hack the web app in any way?
Generally speaking, as long as you are using WSS protocol (as opposed to WS), you are communicating with the server in a secure and encrypted manner. That said, there are a lot of different methods to further ensure safety.
I think a fairly acceptable method is sending username and password once, along with some kind of session ID that is unique to the client. If the credentials are verified acceptable by the server, just the session ID can be passed along with further calls to the server. This cuts down on the amount of times you expose a user's password.
You may want to further secure your credential verification method with some kind of cryptography algorithm such as SALT.
I need to implement a simple remember me option in a java servlet with cookies, without using any advanced framework.
First, at login, I create the cookie and send it in response to the browser (client). The value to be stored in the cookie is just a simple hash from username + password.
How should I manage the incoming request from the browser, sending the cookie?
My approach is to check between registered users if there is any user that has the hash from username + password equal to the value in the cookie?
Is this approach correct?
Also, I did not understand exactly what is the mechanism of the expiration date. Does the browser delete the cookie when it is expired, it not, how do I check if the cookie is expired?
As long as you're not using HTTPS the method you suggest is highly insecure. I would suggest to generate some sort of session token (e.g. use java.util.UUID.randomUUID()) and set this as cookie and store it somewhere on the server side so you later can identify the user associated with this session id in the cookie.
This gives you the opportunity to reset a certain session cookie if you think there's some fraud happening and there's no direct relation between the user name/password and the cookie id you use. But note: this method is still vulnerable to a man-in-the-middle attack.
Concerning the expiration: yes the cookie becomes invalid and might get deleted by the browser if it is expired. But you can set the cookie to something in the year 3000, so it lives forever.
Users log in to my BlackBerry app with a username and password provided at registration. My app connects to a Java Web Service that does all the logic.
How do I go about storing the password and username in a safe manner on my server? Everybody says salting and hashing, but I have no idea how to do this since I've never worked with it. How can I do this in Java?
How do I manage sending the password securely from the app to the server?
To store the credentials, one possibility is to use PBKDF2. A Java implementation (that I have not used) is available here. Run the password with the salt value through that and store the resulting hash data. The salt value is typically a newly generated random value (one for each password). This helps prevent dictionary attacks via rainbow tables (pre-computed tables of hashed passwords). Using java.security.SecureRandom is a possibility for generating those.
The client application should probably connect to the server using SSL/TLS. That will provide the encryption to protect the credentials when passed from client to your server application.
Edit Based on our conversation in the comments, it sounds as if the goal is not to use SSL. Assuming that is true and no other end-to-end communications encryption is planned, then it seems to imply that the security of the communications is not a high priority. If that is true, then maybe the described scheme for authenticating is sufficient for the application. Nonetheless, it seems worth pointing out the potential issues so you can consider them.
The proposed scheme (I think) is to send from the client to the server this value: Hash(Hash(password,origsalt),randomsalt). What this really means is that the password is effectively Hash(password,origsalt). If the attacker can get that information, then they can login as that user because they take that value and hash it with the new salt value to authenticate. In other words, if the database of hashed passwords is compromised, then the attacker can easily gain access. That somewhat defeats the purpose of salting and hashing the passwords in the first place.
Without SSL (or some other end-to-end encryption), there is the possibility of a man-in-the-middle attack. They can either listen in or even impersonate one end of the conversation.
Seems like your question has a few parts...
The most secure way to store the password in the database is to use a hash with a Salt + Pepper seed as described here. If you want to find a good way of implementing that specific technique in Java, try opening a new question.
I can see why it would make sense to encrypt a username/password hash prior to sending to the server, since SSL proxies can be a man-in-the-middle for that operation.
As a solution try creating a token in JSON or XML format that has the following properties:
Username.ToUpper() // Dont want this to be case sensitive
ExpiryDate (Say now plus 5 minutes)
Nonce (a random number that is saved on the backend to prevent replay attacks)
SHA 256 signature
Use the locally entered username and password to create a SHA256 signature, as it will be a constant. Use this signature to sign the JSON or XML you send to the server with each request.
In other words you're using a symmetric key based on the username and password, without sending it across the wire. Of course you may want to salt and pepper the generation of that symmetric key for more security.
That's all I got for a high level design, since I'm not intimately familiar with Java. Do share your links/code when you do find the answers.
So here's what I ended up doing:
package Utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
/**
*
* #author octavius
*/
public class SalterHasher {
private String salt;
private String pepper = "******************";
private String hash;
private String password;
public SalterHasher(String password, String username)
{
this.password = password;
salt = RandomStringUtils.random(40, username);
hash = DigestUtils.md5Hex(password + salt + pepper);
}
public String getHash(){
return hash;
}
/**
* #return the salt
*/
public String getSalt() {
return salt;
}
public String makeHash(String salt){
return DigestUtils.md5Hex(password + salt + pepper);
}
}
A very simple class that generates a salt and the hash for me and has a pepper included for added security, the makeHash() function I use for verification when the user logs in. In view of what I previously mentioned in the comments above I didn't end up using the verification process I proposed and chose to simply add the pepper to my server side code since hashing I believe would prove to be heavy on the BlackBerry device. Thanks again to those who helped me. Good discussions were had :)
I'm curious how does Remember Me work and how does it work in Spring Security?
I understand that server sends long-lived cookies to the client. And then client sends cookie back and server can recognize the client because there's something like hash-map on the server with relations cookie --> session.
I don't understand how does the server [server-side application] recognize a client by cookie after server [Tomcat] has been restarted.
How and where does Spring Security save cookie-session map before server shutdown? Is it server-specific (i.e. something different is happened in Tomcat, Jetty etc)?
P.S. one more related problem with Spring Security and redeployment: even if I don't tick RememberMe and log in, I'm still recognized after redeployment for about 3 mins. Is it fixable?
The Spring Security docs discuss how this actually works.
This approach uses hashing to achieve a useful remember-me strategy. In essence a cookie is sent to the browser upon successful interactive authentication, with the cookie being composed as follows:
base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
...
As such the remember-me token is valid only for the period specified, and provided that the username, password and key does not change. Notably, this has a potential security issue in that a captured remember-me token will be usable from any user agent until such time as the token expires. This is the same issue as with digest authentication.
Basically the cookie contains the username, password, expiration time and a key (which you specify), all of which are hashed together. When your browser sends the contents of this cookie to the server, Spring Security:
Retrieves the password from the backend for the given username
Computes the md5Hex() of the username/password/etc from the database and compares it to the value in the cookie
If they match - you are logged in! If not a match, then you've supplied a forged cookie or one of the username/password/key has changed.
The underlying assumption here is that the hash function - the md5Hex() part above - provides a way to easily encode some piece of data in one direction yet is incredibly hard and unpractical to reverse (to recover the password from the md5Hex text).
Dont' confuse session cookies with Remember Me cookies.
Session cookie is sent by the server (e.g. Tomcat) and used to associate incoming request with the session.
Remember Me cookie is sent by Spring Security to authenticate the client in the different sessions (e.g. after expiration of the original session or after the server restart).
To authenticate a user by Remember Me cookie Spring Security provides 2 strategies:
TokenBasedRememberMeServices - used by default, less secure - cookie contains a hash of the password and other data
PersistentTokenBasedRememberMeServices - more secure, requires database access - cookie containt an unique identifier stored in the database