My security knowledge is kind of limited but I might learn something.I´m planning to create an ajax application where I encrypt/decrypt passwords client-side with a typed master password
using a javascript AES library and then send/retrieve the encrypted data to/from Google App Engine(user authenticated). I actually found a project with the same idea: http://code.google.com/p/safety-vault/
In my mind as long as I keep my local computer secure (keyloggers) this should be quite secure or am I missing something?
As long as you use SSL for the webapp, this should be fine. Without SSL, an attacker could modify the page to insert some Javascript that sends them your password when you type it.
You might want to reconsider your threat model, though. Do you trust the server? If not, you shouldn't trust it to not send you a page that captures your master password when you enter it. If you do, you shouldn't have any qualms in sending your master password to the server.
There is a problem here, as I assume at some point you're going to have to send your master password to the browser client? If you have the master password, then you can decrypt the stream you send...
Use HTTPS, it's what it was designed for.
You effectively are trusting Google App Engine employees, and transitively, the entire trust chain behind them, to not steal your passwords. Encrypting client side doesn't mean anything if you are executing JavaScript code the server sends you, furthermore if you have no HTTPS implemented properly, it's trivial for someone to do a man in the middle attack and steal your passwords as they are transmitted. Just store the passwords locally or encrypt them with a well known tool like GPG and upload them.
Related
I'm building a password manager site using nodejs on the back end. When the user registers and saves a password I encrypt it and then store it in the db, so it's safe. The problem is that I need a safe way to send it from the database and show it to the user when needed. Which is the best way, send it encrypted to the client and decrypt it with a script or decrypt on the back end before sending it? Is https safe enough to protect requests and responses?
Try encrypt and decrypt at device level, so the only risk you take is getting the master password. A good way to do that is with: https://nodejs.org/api/fs.html.
With FS can you write and read data from device level
When making decisions about cryptography, ask two essential questions:
What is your threat model?
Should you be implementing it yourself or use an existing solution (such as BitWarden, an open-source password manager)?
Your seemingly-simple question is tricky, because Web security in general is a complex topic. In an application such as yours, several layers are involved, and you must decide what to do about each of them in your threat model:
Client/browser
Front-end server
Back-end server (can be the same as the front-end server depending on architecture)
Database
Depending on who controls what, the answers will be different. For example, if you're developing a password manager to be deployed on a company's premises, then it likely won't matter whether you encrypt/decrypt on the "back-end" or on the "front-end", as they'll usually end up being the same host, managed by the same IT people. A compromise of the host can result in injecting malicious code, which can then intercept all passwords, keys, etc. right there in the browser, and it's little help that all crypto is done on the client when the client-side code is controlled by the attacker.
In such cases, what will matter more is policy decisions - e.g. if the passwords sometimes safeguard GDPR-subjected personal records, you may need to implement the principle of least privilege and make the journey of the plaintext passwords as short as possible - whether a server-hosted "site" can ever accomplish this becomes an organizational/legal question, rather than a technical one.
Analyze your threat model carefully - what attack scenarios are you defending against? Do different people own the DB layer and the back-end servers, or could a single person dump all DB data and undetectably replace the client-side JS? What do your defenses protect - data at rest, data in transit? You might find that, depending on your desired security properties, a Web-based password manager is not feasible. On the other hand, it may be that you're after simple, single-tier deployments, in which case your job is easier as you can do crypto on the back-end.
The least you could do, if you decide to roll your own password manager, is to look at existing software and learn from it. Pick something that has been audited (e.g. Bitwarden!), find the audit document, see what pitfalls the original authors had run into.
HTTPS is extremely scrutinized that you can assume it's safe, so long you can keep openssl on your system updated. And honestly, your password manager's implementation or maybe your DB/OS patch level is more likely be vulnerable to attacks.
But to answer your question. In theory, decrypting on client side could be safer, but that is only if the decryption truly happens on client side, and that the decryption key is never transmitted over the wire.
That way, even if somebody else gains access to the data or taps data in transit (even with HTTPS decrypted), they will not be able to decrypt it because they will not get the decryption key.
Afterall, that is basically end-to-end encryption like some messaging app does, just in asynchronous fashion.
And why not ask how others do it if you are doing it. For example, 1Password actually built their own protocol called Secure Remote Password (SRP) and they published a white paper detailing the exact intricacies. So you can definitely take reference.
As title shown,
Environment: password is already hash in database, and connection using HTTPS protocol
my question is simple, over the HTTPS, i saw some of the website using SSL, but also doing password encryption in frontend(client browser) when submit form.
Is require?
In my mind, since website is using SSL. there is no need to encrypt password in frontend(client browser). Because whatever frontend(client browser) doing, hacker also can do the same way by using the library(client browser imported the javascript hashing algorithn) to encrypt and send the token. Even put a salt also point less, it just a extra steps for hacker to encrypt it.
Unless the salt is come from other way, not from the same source(page rendering from server). example: from mobile, and using otp as a salt then can resolve.
else i don't think encryption is useful in frontend(client browser).
Am i correct? or i missed out somethings......
The problem is, a website doesn't have any alternatives but to trust in the HTTPS/SSL connection. Whatever encryption you do on client side (browser) will be done in JavaScript and this script must first be sent to the client. A ManInTheMiddle can just do the same as your client does, or he can simply remove the whole script.
It is the same problem you have, when you and your colleague try to invent a secret language, while the bad guy is listening. If you do not already share a secret, this is impossible. An SSL certificate solves this problem, because the browsers have built in a list of root certificates, which will act as the already shared secret.
The situation is a bit different for apps with a client and a server part. There you could install a secret key with your app, and based on this already shared secret you can establish a secure connection.
So the short answer is: yes it is ok to send the password plaintext, as long as the connection is encrypted with HTTPS/SSL.
I would like to encrypt and save a user password in a database, all this with javascript, and later decrypt it. I would like to use a key to encrypt/decrypt all passwords. I was thinking about storing them in an sqlite database.
Do you think this way the database will be secure in case of theft? I guess it will highly depend on the algorithm and implementation.
Can you point me in the right direction to any library that has this functionality, allows me to encrypt/decrypt?
Can you recommend me a library to handle sqlite db. with javscript?
I would normally do all this with some webscripting language without decrypting the pass, but I need to do this with js. and I am fairly new to the language. So any advices would be appreciated.
Thanks!
Client side code should not be used for securing a connection, as the Javascript code itself was loaded from the insecure connection and is thus prone to tampering.
Just load your script and do all sensitive communication through https and and you should be fine.
If you encrypting/decrypting anything, it should be done on the server.
A hacker can view the source code of the JS to figure out the hashing algorithm, and assuming they're using a packet sniffer or similar piece of software, compare that algorithm to the data sent by the user.
For what you want to achieve, you could connect to the server with HTTPS, and send passwords and receive authentication notices to/from the server via xmlhttprequest.
I do not know of any algorithms for doing everything on the client, probably for the reasons listed above. There are plenty of PHP hashing algorithms however. This site may be of use: http://phpsec.org/
Edit: (Read your comment on the OP) Doesn't Firefox offer this functionality already? In any case, saving passwords made on the local machine can be stored on the local machine. When a page is revisited, you could auto-fill the related password fields. The only security threat there is if the host computer is compromised. I don't know any code samples for this though.
Some of the guys here are developing an application which incorporates some 'secure areas' accessible by logging in. In the past, the login form and subsequent 'secure' pages were all plain text transmitted over http, as it's an application that goes out for use on shared servers where there is little chance of being able to use SSL (think WordPress and the like). Most people just shrugged their shoulders as that's all they expected - it's hardly a national bank.
We are now thinking of writing the next version using a JavaScript front end, with the advantage of loading all the images & CSS once, then writing HTML into the DOM thereafter with extJS (or maybe jQuery). We'd like to encrypt user input at the client before being sent to the server, then decrypt server output at the browser before being rendered to HTML so as to introduce some sort of security for users. There are also gains to be had with reducing page loading times, as we're only sending gzipped JSON back and forth.
While playing around, we realised that the method we were looking at to encrypt the basic stuff also doubled up as an authentication mechanism for login in the first place.
For simplicity...:
The user connects to the login page over standard http, where the browser downloads the JavaScript package containing the hashing and encryption algorithms (SHA-256 and AES for example).
User enters username, password and secret into a login form.
The browser JavaScript sends a hash of username and password to the server via AJAX. The secret is only stored in JavaScript and is never sent across the internet.
The server looks up the hash and retrieves username and secret from the database.
The server sends a hash (same algorithm as the browser) of username and secret back to the browser.
The browser JavaScript creates a hash of username and secret and compares it to the hash sent back from the server.
If they are the same, the browser JavaScript encrypts response with secret and sends the message back to the server.
The server decrypts the message with secret to find the expected response and starts a new session.
Subsequent communications are encrypted and decrypted both ways with secret.
There seem to be a few advantages of this type of system, but are we right in thinking:
The user knows they are talking to their server if the server manages to create a hash of username and secret, proving the server knows and understands username and secret.
The server knows the user is genuine if they manage to encrypt response with secret, proving the user knows secret.
At no time is secret ever transmitted in plain text, or is it possible to determine secret from the hash.
A sniffer will only ever find out the 'secure' URL and detect compressed hashes and encryptions in the query string. If they send a request to to the URL that is malformed, no response is given. If they somehow manage to guess an appropriate request, they still have to be able to decrypt it.
It all seems quick enough as to be imperceptible to the user. Can anyone see through this, as we all just assumed we shouldn't be playing with JavaScript encryption!
Don't do this. Please use SSL/TLS. See Javascript Cryptography Considered Harmful.
If you can provide a single SSL site to deliver your JavaScript securely (to avoid the attack mentioned above), then you can use the opensource Forge library to provide cross-domain TLS connections to your other sites after generating self-signed certificates for them. The Forge library also provides other basic crypto stuff if you opt to go in a different direction. Forge has an XMLHttpRequest wrapper that is nearly all JavaScript, with a small piece that leverages Flash's socket API to enable cross-domain communication.
http://digitalbazaar.com/2010/07/20/javascript-tls-1/
https://github.com/digitalbazaar/forge
I'm wondering what the serious issues are with the following setup:
Username/password login scheme
Javascript/ajax requests the salt value from the server (we have established in previous questions salt is not a secret value)
Javascript preforms an SHA1 (or otherwise) of the password and salt.
Javascript/ajax return the hash to the server
The server applies another salt/hash on-top of the the one sent via ajax.
Transactions are over HTTPS.
I'm concerned about problems that may exist but can't convince myself that this is that bad of a setup. Assume that all users need javascript enabled as jQuery is heavily used on the site. It's basically attempting to add an additional layer of security to the plain-text of a password.
As always: be very careful about designing cryptographic protocols yourself.
But that being said, I can see the advantage in the scheme. It will protect against the password being revealed through a man-in-the-middle-attack and it will ensure that the server never sees the actual password, thus preventing some inside attacks. On the other hand it does not protect against man-in-the-browser, fishing etc.
You might want to read through RFC 2617 about HTTP Digest access authentication. That scheme is similar to what you propose.
All that effort of passing salts and hashes between the client and server is already built into the underlying HTTPS/SSL protocol. I would be very surprised if a security layer in javascript is going to help very much. I recommend keeping it simple and use plaintext over SSL on the client-side. Worry about encryption on the server-side.
This doesn't add any additional security. The JavaScript code is present in the client, so the hashing algorithm is known. You gain nothing from doing a client-side hash in this case.
Also, there's no reason why the client should know about the hashing salt. It actually should be a secret value, especially if you're using a shared salt.
I'll 100% disagree with the accepted answer and say that under no circumstances should an original password ever Ever EVER leave the client. It should always be salted and hashed. Always, without exception.
Two reasons...
. The client should not be relying that all the server components and internal networks are TSL. It is quite common for the TSL endpoint to be a load balancing reverse proxy, which communicates with app servers using plaintext because devops can't be bothered to generate server certs for all their internal servers.
. Many users are pathologically inclined to use a common password for all of their services. The fact that a server has plaintext passwords, even if only in memory, makes it an attractive target for external attack.
You're not gaining anything. There's no point to a salt if Joe Public can see it by clicking View > Source, and the old maxim about never trusting client input goes double for password hashing.
If you really want to increase security, use a SHA-2 based hash (SHA-224/256/384/512), as SHA-1 has potential vulnerabilities. NIST no longer recommends SHA-1 for applications that are vulnerable to collision attacks (like password hashes).