Can we store sensitive client information with the admins without them(admins) identifying it? - encryption

I am trying to design a pairing application for my university this valentine. How is it supposed to work, you ask?? The clients will submit preferences to the server and after some days if any two clients have the same preferences, they will be notified -- not in any other case. A fool-proof framework design needs to be built for this purpose. What I am willing to do is to ensure my clients that even though they will be submitting their favourite responses to me via my website, I will still not be able to see those as if I would, this application will have issues of privacy. I am trying to match the user preferences with each other, they will obviously be encrypted and there is no way I can match any two unless I decrypt them at some point in my server locally -- assuming the fact that RSA encryption mechanism has a very little probability of collision of hashed values and I definitely cannot match them :) . The bottleneck here then is >> never ever decrypt the client preferences locally on the admin's machine/server. One approach which is currently on my mind is to introduce a salt while encrypting which will stay safe in the hands of the client, but still decryption needs to be done at some point in time to match these hashes. Can there be some alternative approach for this type of design, I think I might be missing something.

Turn things around. Design a mailbox-like system and use pseudonyms. Instead of getting an email once a match has been found, make people request it. That way you can leave the preferences unencrypted. Just the actual user has to be hidden from public. Start with an initial population of fake users to hide your early adaptors and you will be done.
I.e.: In order to post preferences, I'll leave a public key to contact me. The server searches matches and posts encrypted messages to a public site. Everyone can see these messages (or not, if you design properly) but I am the only one that can read them.

Related

Handling Confidential Data in web application

I want to handle some confidential data in one of my web application. So that the data shouldn't able to read by the Developer or Database administrator.
We can easily hide the data from DB administrator by implementing some encryption technique. But still the developer can see the data since he only creating the decryption technique. I want only the end user should see his data.
I can't encrypt data using some algorithms like PBKDF2 or DB side encryption methods Like TDE & EKM because still I need to keep the encryption key somewhere. If I keep in server side or in db the developer can access and decrypt the data. If I keep it in client side, the user can't access the information from a separate machine.
So How to handle this situation? Thanks in advance.
You are heading the direction of Zero Knowledge Web Applications, such as implemented by SpiderOak (see also crypton). These applications typically work by deriving a key from the user's password using something like PBKDF2, and performing encryption/decryption on client side. However, there are a number of complexities to overcome to make it true zero-knowledge, and also to meet usability requirements. One could write an essay on this, but instead I suggest you start by reading the linked references. If you have any questions, let me know.
In a nutshell, the "more zero-knowledge" you want the system to be, the harder it is to realise without sacrificing usability (one example is overcoming the points made in Javascript Cryptography Considered Harmful). However, there are various tradeoffs you can make in order to make it sufficiently difficult to cheat without affecting usability too much.
I need to keep the encryption key somewhere
No you don't. The user only has to remember it. For convenience you could save it in the browser's local storage.

Best way to encrypt and decrypt persisted data in Node.JS?

I'm writing a Node.JS application that will store chat logs to a datastore (i.e. MongoDB), along with some other user information. I'm already using bcrypt to store salted hashes for user passwords, so I'm covered there.
What the best method of encrypting persisted data? I'm talking about sensitive user data such as phone numbers, and the chat logs. If my database gets compromised, I don't want this information being usable.
I do need two-way encryption/decryption, however, because I need to be able to use the plain-text values (i.e. the phone numbers are for Twilio, the chat logs are for users to see their old messages).
I'm looking into node-crypto but I haven't been able to find any examples of doing this in a performant/realtime fashion.
UPDATE: I should've mentioned that the chat "logs" are actually full conversations that get pushed to "rooms" in real-time when users join them (i.e. they can see the entire chat history, or at least a subset of it). So, I'd need to be able to encrypt and decrypt on the fly pretty quickly (if not in real-time, at least with some sort of worker process).
The best thing to do is use require('crypto').
You will however need to port it to the clientside. Good luck with that. (Shouldn't be too hard with browserify)
Do it all server side, if you do it client side you will need to expose your encryption keys.

asp.net session security

If I put some pretty sensitive information in a session variable, how secure is it? Can it be access by a client writing a rogue page and making an ajax call to my application?
Thanks.
If you really need to store that data between requests, then, you should store in the server side.
To store information to use between requests you have these options:
Hidden Fields: You should never use this to store sensitive information, because the user (or an malicious user) can get that information;
ViewState: You should avoid to store sensitive information here, but if you really, really really need it, you should encrypt the viewstate;
Cookies: You should never use this to store sensitive information. Like the Hidden Field, it's easy to see the information inside.
Session: If you really need to store that data, here is the place you should use. In IT world, there is nothing safe, but this is the safer place to save that information.
I think I didn't forget anything.
In short, because it's stored on the server, it should be safe.
The variable will be safe unless you expose it. You can't just arbitrarily make ajax calls (or any other type of calls) to retrieve session variables. You'd have to be able to write code that executes on the server.
However, if someone is able to hijack your user's session they'd be able to see it on any page you display it (if you do). This security concern isn't restricted to session variables though. If you're worried about this, you might want to use HTTPS.
When dealing with Credit card data you have to be very careful. This is not something you can take lightly as there are all sorts of compliance regulations and laws to consider. Basically, Session is the only place I would consider ... if I did. I would still encrypt it. In truth, however, I would recommend not storing any credit card data if you can help it. There are lots of payment systems out there, and banks provide processing tools as well. If you let the user put it in durring the transaction, keep the entry secure, and store none of it, that is the safest from a legal perspective. You are not bearing risk by keeping the data.
If you MUST keep credit card data see the following PCI regulations:
PCI Compliance Guide
Additionally, you may find this guide on secure session usage helpful:
ASP.NET Fast, Scalable, Secure Sessions

Storing encrypted passwords

My coworker and I are having a fist-fight civilized discussion over password security. Please help us resolve our differences.
One of us takes the viewpoint that:
Storing passwords encrypted using a public key in addition to a one-way hashed version is OK and might be useful for integration with other authentication systems in the future in case of a merger or acquisition.
Only the CEO/CTO would have access to the private key, and it would only be used when necessary. Regular login validation would still occur via the hashed password.
I have/he has done this before in previous companies and there are many sites out there that do this and have survived security audits from Fortune 500 companies before.
This is a common, and accepted practice, even for financial institutions, thus there is no need to explicitly state this in the privacy policy.
Sites like Mint.com do this.
The other one of us takes the following viewpoint:
Storing passwords, even in encrypted form, is an unnecessary security risk and it's better to avoid exposure to this risk in the first place.
If the private key falls into the wrong hands, users that use the same password across multiple sites would risk having all of their logins compromised.
This is a breach of trust of our users, and if this practice is implemented, they should be explicitly informed of this.
This is not an industry-wide practice and no big name sites (Google, Yahoo, Amazon, etc.) implement this. Mint.com is a special case because they need to authenticate with other sites on your behalf. Additionally, they only store the passwords to your financial institutions, not your password to Mint.com itself.
This is a red flag in audits.
Thoughts? Comments? Have you worked at an organization that implemented this practice?
The first practice of storing recoverable version of passwords is plain wrong. Regardless of the fact that big sites do this. It is wrong. They are wrong.
I automatically distrust any site that stores my password unhashed. Who knows what would happen if the employees of that big company decide to have fun? There was a case some guy from Yahoo stole and sold user emails. What if someone steals/sells the whole database with my emails and passwords?
There is no need whatsoever for you to know my original password to perform authentication. Even if you decide later to split the system, add a new one or integrate with a third party, you still will be fine with just a hash of the password.
Why should CEOs be more reliable / trustworthy than other people? There are example of high-ranking government people who have lost confidential data.
There's no reason a regular site has to store a password, not a single one.
What happens if in the future those private keys can be broken? What if the key used is a weak key, as has happened just recently in Debian.
The bottom line is: Why would one take such great risks for little to no benefit. Most companies aren't ever going to need an encrypted password.
Hash Passwords
Storing passwords in a reversible form is unnecessary and risky.
In my opinion, a security breach seems much more likely than the need to merge password tables. Furthermore, the cost of a security breach seems far higher than the cost of implementing a migration strategy. I believe it would be much safer to hash passwords irreversibly.
Migration Strategy
In case of a company merger, the original algorithm used to hash passwords can be noted in a combined password table, and different routines called to verify the passwords of different users, determined by this identifier. If desired, the stored hash (and its identifier) can be updated at this time too, since the user's clear-text password will be available during the login operation. This would allow a gradual migration to a single hash algorithm. Note that passwords should expire after some time anyway, so this would be upper bound on the time migration would require.
Threats
There are a couple of avenues to attack encrypted passwords:
The decryption key custodian could be corrupt. They could decrypt the passwords and steal them. A custodian might do this on his own, or he could be bribed or blackmailed by someone else. An executive without special training is especially susceptible to social engineering too.
An attack can also be made on the public key used for encryption. By substituting the real public key with one of their own, any of the application administrators would be able to collect passwords. And if only the CEO has the real decryption key, this is unlikely to be discovered for a long time.
Mitigation
Supposing this battle is lost, and the passwords are encrypted, rather than hashed, I'd fight on for a couple of concessions:
At the very least, the decryption key should require the cooperation of multiple people for recover. A key sharing technique like Shamir's secret sharing algorithm would be useful.
Measures to protect the integrity of the encryption key are required too. Storage on a tamper-proof hardware token, or using a password-based MAC may help.
and might be useful for integration
with other authentication systems in
the future
If there is no immediate need to store the password in a reversable encrypted format, don't.
I'm working in a financial institution and here the deal is: no one should ever know user's password, so the default and implemented policy used everywhere is: one way hashed passwords with a strong hashing algorithm.
I for once stand in favor of this option: you do not want to go into the trouble of handling the situation where you have lost your two-way encryption password or someone stole it and could read the stored passwords.
If somebody loses their password you just change it and give it to them.
If a company needs to merge, they HAVE to keep hashed passwords the way they are: security is above everything else.
Think about it this way: would you store your home keys in a box that has a lock with a key you have, or would you better prefer to keep them with you everytime?
In the first case: everybody could access your home keys, given the proper key or power to break the box, in the second case to have your keys a potential home-breaker should threaten you or take them from you in some way... same with passwords, if they are hashed on a locked DB it is like nobody has a copy of them, therefore no one can access your data.
I have had to move user accounts between sites (as might happen in a merger or acquisition) when the passwords were one-way hashed and it was not a problem. So I do not understand this argument.
Even if the two applications used different hashing algorithms, there will be a simple way to handle the situation.
The argument in favor of storing them seems to be that it might simplify integration in the case of a merger or acquisition. Every other statement in that side of the argument is no more than a justification: either "this is why it's not so bad" or "other people are doing it".
How much is it worth to be able to do automatic conversions that a client may not want done in event of merger or acquisition? How often do you anticipate mergers and/or acquisitions? Why would it be all that difficult to use the hashed passwords as they are, or to ask your customers to explicitly go along with the changes?
It looks like a very thin reason to me.
On the other side, when you store passwords in recoverable form there's always a danger that they'll get out. If you don't, there isn't; you can't reveal what you don't know. This is a serious risk. The CEO/CTO might be careless or dishonest. There might be a flaw in the encryption. There would certainly be a backup of the private key somewhere, and that could get out.
In short, in order to even consider storing passwords in recoverable form, I'd want a good reason. I don't think potential convenience in implementing a conversion that might or might not be required by a possible business maneuver qualifies.
Or, to put it in a form that software people might understand, YAGNI.
I would agree that the safest way remains the one-way hash (but with a salt of course!). I'd only resort to encryption when I'd need to for integrating with other systems.
Even when you have a built system that is going to need integration with other systems, it's best to ask your users for that password before integrating. That way the user feels 'in control' of his own data. The other way around, starting with encrypted passwords while the use is not clear to the end-user, will raise a lot of questions when you start integrating at some point in time.
So I will definitely go with one-way hash, unless there is a clear reason (clear development-wise and clear to the end-user!) that the unencrypted password is immediately needed.
edit:
Even when integration with other systems is needed, storing recoverable passwords still isn't the best way. But that of course, depends on the system to integrate with.
Okay first of all, giving the CEO/CTO access to plaintext passwords is just plain stupid. If you are doing things right, there is no need for this. If a hacker break your site, what's stopping him from attacking the CEO next?
Both methods are wrong.
Comparing the hash of a received password against a stored hash means the user sends his plaintext password on every login, a backdoor in your webapp will obtain this. If the hacker does not have sufficient privileges to plant a backdoor, he will just break the hashes with his 10K GPU botnet. If the hashes cannot be broken, it means they have collisions, which means you have a weak hash, augmenting a blind brute force attack by magnitudes. I am not exaggerating, this happens every day, on sites with millions of users.
Letting users use plaintext passwords to login to your site means letting them user the same password on every site. This is what 99% of all public sites do today, it is a pathetic, malicious, anti-evolutionary practice.
The ideal solution is to use a combination of both SSL client certificates and server certificates. If you do this correctly, it will render the common MITM/Phishing attack impossible; an attack of such could not be used against the credentials OR the session. Furthermore, users are able to store their client certificates on cryptographic hardware such as smart cards, allowing them to login on any computer without the risk of losing their credentials (although they'd still be vulnerable to session hijacking).
You make think I'm being unreasonable, but SSL client certificates were invented for a reason...
Every time I have anything to do with passwords they are one way hashed, with a changing salt i.e. hash(userId + clearPassword). I am most happy when no one at our company can access passwords in the clear.
If you're a fringe case, like mint.com, yes, do it. Mint stores your passwords to several other sites (your bank, credit card, 401k, etc), and when you login to Mint, it goes to all of those other sites, logs in via script as you, and pulls back your updated financial data into one easy-to-see centralized site. Is it tinfoil-hat secure? Probably not. Do I love it? Yes.
If you're not a fringe case, lord no, you shouldn't ever be doing this. I work for a large financial institution, and this is certainly not at all an accepted practice. This would probably get me fired.

Encrypt data from users in web applications

Some web applications, like Google Docs, store data generated by the users. Data that can only be read by its owner. Or maybe not?
As far as I know, this data is stored as is in a remote database. So, if anybody with enough privileges in the remote system (a sysadmin, for instance) can lurk my data, my privacy could get compromised.
What could be the best solution to store this data encrypted in a remote database and that only the data's owner could decrypt it? How to make this process transparent to the user? (You can't use the user's password as the key to encrypt his data, because you shouldn't know his password).
If encryption/decryption is performed on the server, there is no way you can make sure that the cleartext is not dumped somewhere in some log file or the like.
You need to do the encryption/decryption inside the browser using JavaScript/Java/ActiveX or whatever. As a user, you need to trust the client-side of the web service not to send back the info unencrypted to the server.
Carl
I think Carl, nailed it on the head, but I wanted to say that with any website, if you are providing it any confidential/personal/privileged information then you have to have a certain level of trust, and it is the responsibility of the service provider to establish this trust. This is one of those questions that has been asked many times, across the internet since it's inception, and it will only continue to grow until we all have our own SSL certs encoded on our fingerprint, and even then we will have to ask the question 'How do I know that the finger is still attached to the user?'.
Well, I'd consider a process similar to Amazons AWS. You authenticate with a private password that is not saved remotely. Just a hash is used to validate the user. Then you generate a certificate with one of the main and long-tested algorithms and provide this from a secure page. Then a public/private key algorithm can be used to encrypt things for the users.
But the main problem remains the same: If someone with enough privileges can access the data (say: hacked your server), you're lost. Given enough time and power, everything could be breaked. It's just a matter of time.
But I think algorithms and applications like GPG/PGP and similar are very well known and can be implemented in a way that secure web applications - and keep the usability at a score that the average user can handle.
edit I want to catch up with #Carl and Unkwntech and add their statement: If you don't trust the site itself, don't give private data away. That's even before someone hacks their servers... ;-)
Auron asked: How do you generate a key for the client to encrypt/decrypt the data? Where do you store this key?
Well, the key is usually derived from some password the user has chosen. You don't store it, you trust the user to remember it. What you can store is maybe some salt value associated to that user, to increase security against rainbow-table attacks for instance.
Crypto is hard to get right ;-) I would recommend to look at the source code for AxCrypt and for Xecrets' off-line client.
Carl
No, you can't use passwords, but you could use password hashes. However, Google Docs are all about sharing, so such a method would require storing a copy of the document for each user.

Resources