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.
Related
I will demonstrate my question with an example.
I want to develop a distributed application for renting cars. Since the booking details (BD) can be visible on the blockchain, I want to encrypt them and be accesible only by the intended users. Assume that the car owner and the renter have public key and private key, the car has a key (symmetric encryption) and that the onwer and the renter have agreed beforehand on the BD.
The idea is that the owner will generate an access token, from the BD, which will be published on the blockchain, retrieved by the renter and used by him to enter the car.
My question is how can I encrypt the BD in order to generate the access token while at the same time confidentiality, integrity and availability can be maintained.
One ill-solution that I have thought is that the owner encrypts the BD and their signature with the car's key (in order to generate the access token). Then he publishes the access token to the blockchain and retrieved by the renter. However, how can the renter know that the access token contains the agreed BD? Is it good practice to use a second layer of encryption such that; after the owner generates the access token he encrypts it together with the BD with the renter's public key? In this scenario, when the renter decrypts it, he has two things, an access token (which will be used to enter the car) and the booking details (verify that these are the agreed BD).
Is there a more efficient or elegant way to do this?
Thank you in advance.
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
Option 1: If we use an AWS KMS-managed customer master key (CMK), does that provide end-to-end encryption?
Option 2: Or, would we have to use a client-side master key, so that only the client can decrypt their data?
Update: KMS is not asymmetric, though you can use Envelope Encryption to generate a data key from the CMK. The key is generated on a physical HSM making it not accessible externally. You will only have to worry about the access to the CMK which you can achieve using IAM access control.
For a detailed explanation how the mechanism works, check the Envelope Encryption section on the KMS Cryptographic Details white paper.
So if you only worried about eavesdropping can be a good solution. If you are looking for strictly end-to-end encryption you might have to use asymmetric keys on which KMS can help you with too.
Aws kms does not store any data it provide you two keys
1 plain key : with the help of it you encrypt the data and delete it(key)(no need to save anywhere).
2.encrypted data key :- you need to save this key to decrypt the data( to decrypt the data first you got plain key from aws using encrypted data key) and with the help of plain key you decrypt the data.
So encryption is done at client side.
I learned about the table encryption for MariaDB here.
However, it seems the keys are located in a single file in a way an attacker could easily decrypt the data by having read access on the filesystem.
Assuming that it can be safer, I would like to encrypt database depending on one public key, and connect to the database through a private key file stored on my side.
Is that in any way possible?
It is typical that encryption just moves the problem. It is possible to protect the key in storage but not easy or cheap and it is virtually impossible to protect it in RAM when being used by the DB.
Solutions to protecting the key in storage include moving it to an HSM or another more secure and limited access system that provides the key to the DB over a secure link.
One advantage is that is the DB is obtained without the key it is secure, the problem is that the same access can also provide the key to the attacker. The work factor has increased and that may meet the security needs.
I am developing a web based application that will be employed by numerous third party organisations
in numerous countries around the world.
The browser based client will feed sensitive data into a shared back end database.
All organisations in all countries will Read/Write data into the same database.
I wish to encrypt the data entered within the browser so that its safe while in transit
to the back end database. e.g. client side encryption.
I also wish to encrypt the data while at rest in my database.
This application will be developed using Java, Javascript (REACT.js), and Scala.
The backend database will be MongoDB.
I cannot find a good Key Management example/description e.g. how a key is properly generated,
distributed, stored, replaced, deleted, and recovered during its life time.
I have the following choices/decisions to make:-
Flavour of encryption, e.g TripleDES, RSA, Blowfish, Twofish, AES etc..
Key(s) Symmetric/Asymmetric and its/thier length
How should I securely distribute the keys to my clients.
How to keep my keys safe on my back end servers.
If keys should have a lifecycle of generated, distributed, stored, replaced, deleted.
How do I decrypt data that was encrypted with Key0 when I am now using Key1, or Key2?
How should I store my multiple keys for my multiple clients to enable me to encrypt/decrypt
each clients data.
Use HTTPS with certificate pinning to secure the data in transit.
Use AES for encryption. Do not use TripleDES, RSA, Blowfish or Twofish in new work.
Use an HSM.
Encrypt the data with a long-life key that is not distributed, encrypt that key with short life keys that can be changed as needed.
Considering the scope of the project get a cryptographic domain expert to design the security and vet the code.