Hint needed: Encryption of shared content. How to organise? - encryption

I'm not quite sure how should I handle this generally.
Here's the situation:
I'm planning on a service where one can share content with other people.
For the time being I'll name the Person who is sharing the content Alice and the two persons that the content is shared with Bob and Carol. Alice is a sharer; and Bob and Carol are observers
Alice is sharing some documents …:
Document A is shared with nobody
Document B is shared with Bob
Document C is shared with Carol
Document D is shared with Bob and Carol
Document E is shared with Bob and is planned to be shared with Carol in the future
Document F is shared with nobody and is planned to be shared with Bob in the future
Document G is shared with Bob, but should be shared with Carol instead of Bob in the future
...
Of course Bob and Carol can also be sharers, and Alice can also be an observer.
Let's assume that Bob and Carol might not be IT experts, so they wouldn't know, what to do with a public/private key pair. Alice as a sharer is the active subscriber to the system and Bob and Carol are invited to the system, so they won't know too much. Therefor the encryption/decryption should be managed in the background automatically. This would mean that the private key will be stored somewhere on the server, or wouldn't it?
You see, there are quite a lot of use cases in these scenarios, and I'm not sure on a good way to organize this.
Where should I store the public/private keys so that only Alice, Bob or Carol can use them and only, if they are allowed to?
Should I create a public/private key pair for every user, every sharer/observer pair, or for every document?
Should I decrypt the documents in the Browser (Angular) or already on the server side (express/NodeJS)?
Should the keys (at least the private one) be encrypted by themselves?
The documents should be stored on Amazon S3. Should I create a bucket for every user?
How can I make sure that I can deny any access that I had granted before
The tech stack does not seam to matter the most, but it's MEAN (MongoDB, Express, Angular2, NodeJS). It also uses NgRx store.
What I don't need is a full-fledged program, but only some nudges in the right direction. If you happen to have one at hand, I won't reject it :)
Edit: Summary
Here is a short summary of the scenario:
Alice should be able to share documents with Bob. The documents should be encrypted so that only Alice and Bob can read them. The sharing is through a web app in the browser.
Edit 2:
Oh, and BTW, Alice and Bob or Alice and Carol don't need to be online at the same moment, or at the moment that Alice shares the documents. In fact they are shared to be used several years later.

You should:
Encrypt data at rest
Ensure your application only grants file access to authorized users
Systems such as Amazon S3 normally create a per-object encryption key to encrypt the files. Then, that key is encrypted with a master key. The master key is kept in the Key Management System and can never be exported.
This way, if one of the encryption keys is obtained, it can only be used to decrypt one file. Or, if a government demands access to a file and therefore demand the encryption key, they can only read that one file.
Amazon S3 can manage all of the above for you automatically by using server-side encryption and AWS Key Management Service.

you do not think that I can add extra security by making this process extra complicated?
Making the process more complicated is usually prone to more complicated mistakes.
In theory - you may create an end-to-end security by encrypting content by a content key and then encrypt the content key for each accessing user's public key. Though each user needs to have its own private key by himself and able to use it.
already on the server side (express/NodeJS)
Ok, you have a server side application so that makes the things easier.
Seeing your requirements you may not need to manage the access directly on S3. To simplify the things - you may create an application which decides which user may or may not access the content. Then the application may provide the content either directly (e.g. proxying the S3 content) or providing a signed url for access the content. That assumes you keep the application credentials secure.
The documents should be encrypted so that only Alice and Bob can read them.
...
Therefor the encryption/decryption should be managed in the background automatically.
You may encrypt the content on S3 itself, though it will be transparent to the users, they will receive the content plain.
If you happen to have one at hand, I won't reject it :)
You may have check any content management or portal solutions, they provide access and content sharing by defaut (Aflresco, Liferay, ...) or any feasible CMS system

Related

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

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.

Decrypting customer data on the client side

I have a web app which my customers use to allow their employees to exchange documents. So, employee A1 can upload a document which employee A2 can later access given that both are employees of customer A. However, employees of any other customers are not allowed to access files uploaded by A1.
I would like to extend the web app to support secure documents. This means that I would have to encrypt document content before storing it on my server. In order to reduce liability I would like NOT to be able to decrypt the document content. So, ideally the content would be decrypted on the client (browser) side.
I have considered solutions that require an extra decryption/encryption service to be deployed on the customer side, but I don't like the extra management overhead that they require.
Assuming that my customers are large corporations and would have the typical infrastructure, e.g. LDAP, how would you propose to solve this problem without deploying extra services in customer environment?

Encryption Scenario and Recommended Practice

We are trying to develop a system that can control end-user decryption without the ability to decrypt the data if we hold it. The end user can encrypt/decrypt when we send them our key in conjunction with their key.
Or (we are Bob below)
Alice generates two keys. One for her, the other for Bob.
Assume Alice will have Bob's key only when needed (controlled operations).
Alice encrypts a blob using her own and Bob's key.
Bob's key alone can not decrypt Alice's blob.
Alice's key alone cannot decrypt her own blob.
Eve has access to Alice's key and blob. Eve cannot decrypt Alice's blob.
Which crypto system, if any, does this scenario portray? To me it is Diffie-Hellman, except the first step, Alice generates two keys.
Does such a system exist or can you recommend a best practice for this scenario? TYIA
You're probably looking for Secret Sharing schemes, which make it possible to require t of n users operations. (In this case, 2 of 2.)
An excellent reference is the Handbook of Applied Cryptography, Section 12.7 Secret sharing.

Encrypting Salary value in ASP .NET 2.0 and SQL Server 2005

I have an ASP .NET 2.0 website connected to a SQL Server 2005 database. The site is pretty simple and stores information about staff, including salary.
What is the best way to encrypt the salary value so no-one (including myself) can ever see what it is, except for the authorised staff using the web-app?
I don't want to encrypt / decrypt on the SQL Server because I could just run SQL Profiler to view the information, so I assume the encrypt/decrypt happens in the BLL on the web server?
Also, do I need SSL to stop someone sniffing HTTP responses between the browser and the web server?
Many thanks!
Anthony
SSL is probably your best bet to keep someone from sniffing, but be aware that it is still possible.
As for the other bit, SQL Server 2005 supports table-level encryption out of the box. Here's an article on it. You could create a SALARY table that is linked to an employee and keep that table encrypted.
Developers of the webapp could still access the salary figures -- it's all a matter of trust. To counter that, you could switch to the model where the encryption/decryption happens on the client-side, but this is more cumbersome and still not 100% secure. Security is always a trade-off with convenience.
You should use TLS/SSL (i.e., HTTPS) so that eavesdropping on the HTTP traffic is harder to perform.
An attack you may consider, is replacing your own encrypted salary figure with that of the person you are interested in, then calling up the accounting department and asking what your current salary figure is. One way to negate the attack is to have the contents of the encrypted salary field reference the person it belongs to.
There are many encryption methods you could use here in your code. Make sure you choose one that takes a key and a "salt" (as opposed to just using the same key each time). If you use the same key (without a salt) each time you encrypt a salary, then two employees with the same salary will display the same encrypted value in the database, compromising the security of the salary info.
You could use each employee's unique ID as the salt.
You definitely need SSL to prevent sniffing of the sensitive web traffic (not to mention logins), but that doesn't solve your server-side encryption problem.
To make it impossible for you as the developer to access the data is a tough nut to crack. In order for it to really work, all the encryption/decryption needs to be done only on machines that you have no access to. Theoretically you would have to make some sort of browser extension that decrypts the salary data on the client machines. Your employer would have to trust you enough to not put a backdoor into the client-side code (or at least hold the possibility of a code audit over your head).
In most cases, it is easier to trust the developer to not disclose the data. It's a good idea to keep it on a need-to-know basis, but ultimately some people need to know. (For instance, accounting people see salary data all the time.)
You definitely want to use SSL for the transportation security. You could also setup IPSec for the transportation between the web server and database server.
As for securing in the database, SQL Server 2005 has several encryption functions:
1) EncryptByAsymKey - http://msdn.microsoft.com/en-us/library/ms186950.aspx
2) EncryptByKey - http://msdn.microsoft.com/en-us/library/ms174361.aspx
3) EncryptByPassPhrase - http://msdn.microsoft.com/en-us/library/ms190357.aspx
4) EncryptByCert - http://msdn.microsoft.com/en-us/library/ms188061.aspx
Obviously, all of these have an associated decrypt function.
You can store the key or whatever you choose on the web server (in the machine.config or web.config or somewhere) and then pass it to your stored procedures (or along with your sql somehow) for the encryption.

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