Javascript password hashing for sending insecurely - javascript

I want to send a password over HTTP.
Scenario:
User enters his username and password into a form.
Password is hashed and sent to the server with the username.
Server checks password hash and username and authenticates user. (the server doesn't know the plain text password either.)
If someone somehow intercepts the authentication message, he will obtain the hashed password and username, and he could potentially log in to that user's account. Essentially, the hashed password IS the password, according to the server.
Here's the thing: I don't care. It's rare enough that someone would have that data hijacked, and even so, it's not really a problem if your account gets stolen, you can just make a new one.
The Question: What is a good way to hash the user's password in JavaScript? The hash can't use random salt since it needs to be recognized by the server.
The only thing I am concerned about is the user's plain text password being found out if the message is intercepted. The reason being that the plain text password could also be used to compromise other services the person uses that may actually contain important information.
EDIT: to clarify, the question is mainly about what hashing algorithm to use, and if there is a lightweight library for it.

If security is actually not an issue, e.g. it's okay for people to compromise your system, and the only reason you want to salt the hash is to prevent the use of rainbow tables and the plaintext password from being determined, then do this:
Compute a sufficently long salt for every password on the server, and store it on the server (just like how most systems typically stores the password in the DB)
Send the salt to the user in plaintext
Compute the salted hash and send back
If I'm thinking about this correctly, this will still prevent the use of rainbow tables.
Otherwise, just go with https? :P

Related

restful service requires username and password to get the token, is it ok to save the credentials(user and pass) in server side nodejs?

I have a app which takes a csv from user, converts it to json and saves the json file in S3 bucket on AWS. Then I am using restful services from oracle to push that data to oracle jde.
User can't upload a file without being "approved" before hand - its a manual process for now, but their email needs to be added to S3 bucket first
The web app checks if the email exists in S3 then allows the file upload to happen, if it doesn't exist then file upload is rejected.
I don't have any other "user authentication" set up for now.
Next, in order to get the token from the external API, I need to feed it a service account username and password, currently, since its still in development I am keeping the username and password on my server side nodejs in a object which I pass into the api call to get the token.
For the time being we don't plan on having user login, so that being said how can I secure the username and password but still be able to get a token for "authenticated emails allowed to upload"?
Basically, I assume just keeping it in variable server side node is not a good idea, so looking for another way of storing it somewhere and still being able to make the call to the api.
For the time being we don't plan on having user login, so that being
said how can I secure the username and password but still be able to
get a token for "authenticated emails allowed to upload"?
You can't. Unless I'm misunderstanding something, those are not "authenticated emails", they are "pre-approved email addresses". You still need to authenticate your users to help secure the app.
So do I still hash and salt the hardcoded username and password and save to db?
You can't salt and hash your passwords because you're intending to reuse the original password. That puts the onus on you to secure the passwords. Don't play that game. Many people reuse the same passwords for lots of different accounts. Do you want to have to send an email to your users letting them know you had a security breach and that they need to reset all their passwords?
Basically, I assume just keeping it in variable server side node is not a good idea
That's right, it's not a good idea. For example what if your server dies? Then you'll loose that value. Not to mention the added cost of your RAM since everything will be stored in memory.
Solution
Store the credentials in a database. It can be in SQL or NoSQL, and the server can be in whatever you prefer
Considerations
Don't forget to hash the password before storing it
Add some salt when hashing
To validate a password, just hash the one you got from your client and compare it to the hash you stored in your database
Use HTTPS for traffic between your client and server

Is it possible to have more than one password with js encryption?

I am currently using an encryptor project on my website. https://robinmoisson.github.io/staticrypt/
It encrypts HTML files and shows a password prompt and when the password is guessed right it decrypts the website.
My question is, is it possible to have more than one password with this project. Instead of having only one password? I would like it to work with multiple passwords.
Any help is appreciated
I understand your question are because you didn't know how the encryption systems works.
You cannot use multiple different passwords, because the password itself are literally the key of the encrypted content.
If you use a different password for encrypt content, then you have a different result (a different encrypted result). Because this, you cannot have multiple passwords for decrypt the same data.
The only option, if you want to have different passwords, is to process it at server level. The client sends a password, these password are processed at server side, and if the password are valid (you can have a database with passwords for a user or a list of valid passwords), then you send the content. You can also use a system to send the decryption password to the client, encrypted with a user-level password. For example:
The client fills a username field. These field are sent to server. Server retrieves the password for these user from a storage at server
side, and then, encrypt content with these password. At last, the
content is sent to the client encrypted with the user password, who
will need to enter it to read these content.
I think these method are the best method to achieve what do you need. But I understand is not your request, is an approach to do it.

Storing passwords to login to 3rd party APIs

I am writing a trading application using Node & Express for the backend. Each user will have their own login for the application itself, but in order for it to be useful the application also needs to login to the user's brokerage account.
The brokerage account in question has a REST API in which you POST the login and password for that system. That API does not offer SSO or OAuth as an option for authentication. The only means to authenticate is POSTing the uid and password.
So there are two logins involved here: one to my application, and another completely separate login to the brokerage account. Each of those logins uses a different user ID and password.
The problem I'm having is figuring out how to store the password for the brokerage account. I understand that storing a password at all is a bad idea. But if all I store is a salted hash of the brokerage password, I wont be able to reverse that and get the actual password back. Hence, my application won't be able to login to the brokerage account unless the user enters that password again.
(As an aside, there is another program that does this. https://dough.com requires the user to login to dough, and then you also have to login to TD Ameritrade. That logging in twice is what I'm hoping to avoid.)
Is there a reasonable and secure way to store a password for this 3rd party API so that my app can login on the user's behalf without forcing the user to submit the password every time they use my app? I understand there are big security risks here. If the answer is no, then I won't.
Edit & Obligatory - Really the solution is to not do this. While technically possible, it will almost certainly not be implemented correctly & will expose your users' passwords.
Yes there is, but it's not incredibly easy & implementation is key. The JavaScript OpenPGPJS library is what you want.
In order for a somewhat secure system, your backend cannot be allowed to decrypt the password. This is where the JS library comes in, which provides PGP crypto via the browser.
You can base the PGP password off of the user password, or make them provide a new one for decryption. Alternatively, you can generate random keys for the password encryption then create a master key with access to the random ones - encrypting the master with the user input.
Whichever method you go with you will either need to have them enter the password in order to decrypt the record when needed, or add their password into their local session. The former is secure and the latter has obvious security implications.
Simple string encrypt using a password as provided by the examples:
var options, encrypted;
options = {
data: 'Hello, World!', // input as String
passwords: ['secret stuff'] // multiple passwords possible
};
openpgp.encrypt(options).then(function(ciphertext) {
encrypted = ciphertext.data; // '-----BEGIN PGP MESSAGE ... END PGP MESSAGE-----'
});
Decrypt:
options = {
message: openpgp.message.readArmored(encrypted), // parse armored message
password: 'secret stuff' // decrypt with password
};
openpgp.decrypt(options).then(function(plaintext) {
return plaintext.data; // 'Hello, World!'
});
I think you have a few options, and the decision you choose should depend on the risk you want to take. If it is financial data as you hinted, I think the decision should clearly be not doing any of this.
One option is to store the 3rd party API password encrypted on your server with a key derived from the user's local password. As you don't store your user's local password, you can only decrypt the 3rd party API password upon user logon when you have his local one, and from there if you want to make future calls to the API impersonating the user, you will have to keep the plaintext version of the 3rd party password in server memory (the user's session). I think that while in some applications this could probably be a viable option, for financial data this is unacceptable.
Another thing you could do is encrypt the 3rd party API password in Javascript as Dave Lasley described in his answer. While that could work, it adds a lot of complexity, and as he also pointed out, implementation would be key. It would be hard to get this right and maintain over time without introducing vulnerabilities. Also Javascript crypto has its problems, the best practice is to not do cryptography in Javascript. You would have to keep the 3rd party API password in Javascript memory, which is a very weak control, any single XSS would be able to steal it from there (any other browser store is even worse than a Javascript object in memory). Also the 3rd party API would need to support CORS from your domain (or * obviously).
My take is that pretty much the only good way to do this would be a careful implementation with OAuth2. If the API doesn't support that, then you should not do this at all unfortunately.

Sending hash password to WebAPI

I have a WebAPI application which is working fine. There are no problems loging, registering etc. However, I come across something which requires some attention. When somebody is registering or logging then their passwords are sent in plain text. I know we can apply HTTPS certificate and this will be solved. However, I am more looking for a solution where I can hash password and WebAPI can automatically pick it up. I am not looking to make changes to built in WebAPI functionality to hash and store PW. This is to also make sure that when I am using FF or Chrome developer tools then nobody can read the PW from data being sent.
I am using Angular or JQuery AJAX to make calls to my WebAPI.
It is possible to encrypt the password in the frontend and send the hashed password and salt + rounds (when used) to the server.
Problem arises when the user tries to log in, you need to get the salt and roundings to the frontend, hash their password (which the typed in) send it to the server, there you do a compare like hashedPassword == hashedPassword and return true/false.
So in my opinion this is less secure than just doing all on the server side. Only benefit is, that no one can see your password in your dev-tools or in the payload.

Submitting passwords via ajax

given the following scenario: We have a html form for changing an account's password. It looks like this:
CurrentPassword: __________________
NewPassword: __________________
NewPasswordAgain: __________________
We want to send this request via an ajax call. If we send it and we leave our computer (without logging out and staying on the exact same page) someone could open the webkit inspector (or firebug) and see something like this:
http://cl.ly/3y213W1q0U2y2e251k0O
What would be your solution for making this more secure? Is it even possible using an ajax call here or would it be better to use a "normal" html form which reloads the whole page after sending?
Using a "normal" html form has the same problem, as packet sniffing could reveal the same data in a POST or GET header just as easily.
The best solution I can think of is to encrypt the password user-side via javascript. You don't really have to worry about the "what if the user has javascript disabled?" case since, in that case, the AJAX request won't go through either. Obviously this may have ramifications regarding how you store the password, but it will allow you to continue to use AJAX requests for the password update.
The author is not interested in encrypted connections here. He may as well be doing that already. What he wants is to be able to hide the password (and username) from any one who has an access to the computer, and can open the inspector tools to view the networking that occurred on the page.
One of the simplest things you could do is to refresh the page in case the authentication succeeded.
Something that you should do is to refresh the page whenever the user pressed "log out". This should clear all previous network data.
The less good options are about encrypting, obfuscating and hashing the password prior to sending it.
Hashing the password on client-side is not ideal because this prevents the use of hashed passwords with keys on the server-side (think HMAC). HMAC'd passwords are the best, because the key is kept on the filesystem whereas the salt is kept on the database. Cracking the password hash requires a rather solid access to the system.
Obfuscating and encrypting the password can be reversed. If someone sees a login request on the Webkit Inspector, he might be very interested in spending the time to undress your defenses.
I highly recommend refreshing the page at some point to avoid the problem entirely. Other options do not seem as good.
Encrypt the password on transport and make sure the calls you are making are being done over SSL!
To make this secure without using SSL, hash the passwords on the client using SHA-2. While that will protect the password itself, it won't protect someone from sniffing the hashed password. So you can't simply authenticate with the hashed password, either.
One way to do this is to use a server-generated random salt when authenticating. To authenticate, the client requests salt from the server, then hashes the password once (in order to match the hashed version stored on the server), then hashes again using that salt that it received from the server, then finally authenticates using a second ajax query with the salted-hashed password.
The server will authenticate only if this matches its own stored hashed password, hashed with the same salt it previously provided the client.
This way, it is impossible for someone to authenticate using the simple hashed version of the password. Since each salt provided by the server is valid only once, it would be essentially impossible for someone to intercept it and authenticate. (They would have to intercept the salt request, and then try to authenticate before the legitimate client could, all the while spoofing their session).
This protects users' passwords without using SSL, prevents logging in using data intercepted while the legitimate user is authenticating, and is fairly easy to implement. Of course there is no substitute for SSL as far as protecting the actual data on your site, but for a lot of typical web sites where there's not really any sensitive information, you should be more concerned about preventing theft of your users' passwords since people use the same password so often. This addresses that problem.
Note that this also does nothing to prevent session hijacking, but you can minimize the risk and damage of this by doing things like including browsers-specific information with the users's session, and allowing only a single active session at once, and requiring re-authentication to change email address or password.
Depending on the level of security you need, you could use RSA and public-key cryptography to encrypt the password within the browser prior to sending the ajax request. On the server-side, you would decrypt the passwords and process them as normal.
Of course, you would also need to be careful to delete any variables used to hold the entered passwords, and I am sure there are other security holes in this, but encryption will at least offer you some large degree of protection against that sort of attack.
Here's one library I found with a quick search. (disclaimer: I have not tested this, but it looks pretty good)
Lastly, I would strongly recommend that you transmit all login information via SSL. This adds an extra layer of security on top of the whole browser session between the browser and your server.

Categories