I am implementing an API in rails and would like to use HTTP digest authorization as it is more secure than basic authorization. How would one achieve this if my passwords are stored in the database as a one way cryptographic hash.
Honestly? Don't bother. If you're going to use Digest over HTTP, you might as well be using forms or basic auth. HTTPS is the solution. Using Digest is still totally insecure (it uses weak hashing and it provides no defense against MitM attacks).
HTTPS is not hard and without it you are going to have a very hard time securing your application.
The only way to use digest authorization with hash values stored on the server is to duplicate the hash algorithm on the client to turn the user's password into the hash, which then basically becomes the new password (shared secret key).
If you used a salt when generating the hash values, you'll need to use the same salt on the client, which may prove difficult.
As others have suggested, consider using HTTPS instead. You can then send the passwords in plain text from the client to the server and rely on HTTPS for the end-to-end protection. HTTPS provides both encryption and authentication, which closes the loop.
Related
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
My team are coding a web app, which include a server and a client, I think it's obviously not advisable to send user's uid and password to server every request from client.
I am looking for a good choice to deal with this, maybe something like Oauth, is there any efficient approach?
For example, a user with username lyj and password 123456 request login from my client app, the server should check if it is permissible, after login success, the client can send more request to get other resource from server.
My problem is that, except userid and password, is there a way between server and client to make sure who is this guy, is there any suggest to transmit a access token between server and client?
Without much information on your platform and technologies I can only attempt a generic answer. There are several ways in which you can generate a token depending on how you want to use it. MD5 is a well established algorithm and you can use it to generate a oth token using something like username and email etc. Remember that you cannot decrypt MD5 string. So to do any kind of verification you will have to recreate the string using original parameters and then perform a check. If you want a hash that you can reverse you can look at something like base-64.
Both MD6 and base-64 are easily available as libraries in any back end you may be using.
* UPDATE
Looking at your comments that you are working with a stateless client, here is a possible approach to using tokens.
Client performs login for first time. (preferably HTTPS)
Server performs validation and generates a token using MD5(or any other of your choice) using (username+email+ip_address+time_stamp) and sends it back to client
Server creates a new session for this client in the table in the database using userID , ip_address and, time_stamp
Client passes this token back for any future requests.
When client passes the token , server retrieves the session from the database and generates the MD5 hash and compares it with the token client sent. If its the same you are good.
You can also use the time-stamp value a validity window for your tokens so they are not valid forever. Also its impossible to recreate this token unless someone can create the same MD5 hash at the same time down to milliseconds
Modern web application containers have embedded the session tracking functionality. Of course there is always the choice of cookies. Its up to you what to implement...
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 having a form that dont actually saving a model, so When i do POST the form, there is email and password, but somehow I dont want to expose my password to others.
I did this
config.filter_parameters to filter in the log
but when I POST and I check browser, there are still having plain text for my password which I dont want to. Is there any proper way to encrypt the params when sending that when I inspect in the browser, everyone will just see hashes or encrypted.
Oh ya,I meant the way not using SSL as well >.<
If you can't use SSL, then you can't be secure.
Even if you did private/public key encryption with JS before sending the passwords over the network, you can't trust that your encryption JS code wasn't compromised when being sent to the client. After all, you want to encrypt because you are worried about network vulnerabilities.
Of course, you could use JS encryption over an insecure protocol to give the illusion of security. To be fair, the attack to compromise the passwords in this scenario would need to be more sophisticated than simple network sniffing.
A great article on this topic is here: http://www.matasano.com/articles/javascript-cryptography/
I'm probably confusing concepts, but I've been discussing on the web2py Google Group that they should implement digest-authentication.
With OAuth2, I'm thinking that the auth-key should be hashed and only sent within an authentication realm.
If it makes a difference, I'm using JavaScript client-side, interfaces are exposed with JSONRPC server-side, and OAuth2 is done with Facebook.
Should I negotiate OAuth2 inside a digest realm?
You are confusing things - there's no notion of digest realm in OAuth. There's also no such thing as an 'auth-key'.
What you have is an auth-token, which represents a claim that you have been issued by a user/entity.
Since the token represents the [client_id, user, scope, expiration] tuple, it can not be used to produce a hash as that hash would be useless - the Resource Server cannot hash every possible combination in order to find the match.
If you want transport security, simply require SSL (not accounting for MiTM-attacks with valid certs and so on).
That said, protecting the credentials (the token) using a digest is pretty useless when the attacker is already in a position to intercept your traffic...
Also, to add something to the story behind OAuth2 - the reason it is so simple (relying on SSL for protection) is that this is something that is manageable by pretty much everyone.
The more complex something is, the higher the odds of something going wrong.