dchest / tweetnacl-js

Port of TweetNaCl cryptographic library to JavaScript
https://tweetnacl.js.org
The Unlicense
1.77k stars 293 forks source link

Can I encrypt the string with several public keys and decrypt with any private? #151

Closed evgeny-s closed 5 years ago

evgeny-s commented 5 years ago

Let's say I have 2 pairs of keys: PUB_1/PRIV_1 PUB_2/PRIV_2

I need to encrypt some string, let's say "Hello world" with both keys PUB_1 and PUB_2 and decrypt the string with any of PRIV_1 or PRIV_2?

Thank you in advance.

joeldrapper commented 5 years ago

If you have PUB_1 and PUB_2, can’t you simply encrypt it twice? Then you chose which one to decrypt depending on which private key you have.

evgeny-s commented 5 years ago

Because we need to decrypt the data with PRIV_1 or PRIV_2, not with both. I don't want to store 2 encrypted strings. I want to store only one encrypted string and be able to decrypt with any of private keys.

joeldrapper commented 5 years ago

Could you encrypt the data with PUB_3, and encrypt PRIV_3 with PUB_1 and PUB_2?

evgeny-s commented 5 years ago

In this case, I need to store somewhere PUB_3 and PRIV_3, but I don't want. The scenario is the following: John - he is a user of the application let's say Mortal Kombat. The application wants to store some user data, but it wants only the user and the application can decrypt this data. So, the user has its own key pair and the application has its own key pair.
Application encrypts this user data with both public keys - user public key and application public key. After that, the application should be able to decrypt data without the user's key and vice versa.

dchest commented 5 years ago

Generate a random secretbox key, encrypt data with it, then encrypt the key with PRIV_1 and PRIV_2, attach both results to encrypted data.

evgeny-s commented 5 years ago

Generate a random secretbox key, encrypt data with it, then encrypt the key with PRIV_1 and PRIV_2, attach both results to encrypted data.

I don't want somebody to pass his private key to some other parties. So would be great to encrypt with the public keys and decrypt with a private key.

dchest commented 5 years ago

nacl.box works by calculating a shared secret key from recipient's public key and sender's private key. How is passing another key would be different from passing this shared key to other parties (or for that matter, passing the private key)?

alax commented 5 years ago

I move that we close this issue.

I'm sure a lot of us are subscribed to watch for actual issues/other things relating to this project, and this does not meet that criteria.

evgeny-s commented 5 years ago

ok, let me describe the flow:

  1. application generates string - "Hello world"
  2. ask the user about his Public Key
  3. user gives his Public Key to application (no privacy violation)
  4. application encrypt this string with both Public Keys: it's public key (application's) and user's public key.
  5. application stores encrypted string in the database.
  6. once user wants to show the data - it takes the encrypted string and decrypt it with his private key
  7. the same thing for the application.

The question is - is it really possible with this library or not?

joeldrapper commented 5 years ago

@evgeny-s This isn’t an issue with the TweetNaCL JS library, or a feasible feature request. You should be able to get some good crypto advice on the right protocol to use from here. https://crypto.stackexchange.com

evgeny-s commented 5 years ago

Thanks!

dchest commented 5 years ago

@evgeny-s to answer your question, there's no function for encrypting with multiple keys in this library, so you'll have to build your own.

bkniffler commented 5 years ago

Just in case, theres a question on stackoverflow: https://security.stackexchange.com/questions/68606/nacl-encrypt-file-to-multiple-recipients

Here the top answer:

The actual format of NaCL's output is not completely specified -- or, rather, it is specified as being the raw output from some cryptographic primitives (as described there). The format is thus non-extensible and does not include any feature supporting multiple recipients. Ability to send a message to multiple recipient appears to be a functionality that has been sacrificed on the altar of simplicity.

If you want to use NaCL and still send a single message to multiple recipients without duplicating the bulk of the data, then you must design your own format, basically doing this:

You generate a random secret key K. You use K to encrypt the message (with crypto_secretbox). You encrypt K as if it was the "message" with crypto_box.

But then you are defining your own protocol, built over existing primitives. This is the exact kind of things that NaCL was meant to prevent. Or, said otherwise, if you are back to doing your own protocol design then why would you use NaCL ? And, in any case, you would be on your own, both for the security analysis and the implementation (since you would not interoperate with anybody else).

If what you need is what OpenPGP provides, then use OpenPGP.