Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asymmetric encryption functions for long-term / re-usable encrypted data storage #333

Open
Arteneko opened this issue Apr 2, 2023 · 5 comments

Comments

@Arteneko
Copy link

Arteneko commented Apr 2, 2023

hi! I'm wondering if there was some plan (or something already available) for adding functions for long-term asymmetric encryption?
I see the KEX module but it's explicitly documented as for single-session message encryption, so I don't think it's usable for this goal too?
The context is to allow a user to safely encrypt+store some data without having to authenticate themselves (ie with their public key, so a "single known public key").
If that isn't a recommended pattern or usage, what would be the best alternative?

@brycx
Copy link
Member

brycx commented Apr 3, 2023

What it sounds like you're looking for is a Key Encapsulation Mechanism (KEM) and probably hybrid encryption. We do have the available primitives for this, specifically a KEM instantiation of X25519-HKDF-SHA256.

A way to accomplish this, is how age encrypts files. What you would do here is have a recipient's public key (the key of the user that should be able to decrypt the data later on), which you would use to derive a symmetric key, used then to encrypt the actual data (some details omitted here). This is sometimes referred to as an ECIES scheme, or a more formalized and proven construction: HPKE - RFC9180. A user would however still need to securely manage a X25519 keypair (instead of say, an encryption passphrase).

That said, I'm open to add an implementation of the HPKE variant using DHKEM(X25519, HKDF-SHA256) + ChaCha20Poly1305 from the RFC, if this is something you're interested in using?

@brycx
Copy link
Member

brycx commented Apr 3, 2023

What's the size of the data that needs to be encrypted? Are these files or something that can fit into memory?

@Arteneko
Copy link
Author

Arteneko commented Apr 3, 2023

The size of the data that needs to be encrypted ranges from a small textual value of 20-30 bytes to some image/video files that may take a few MBs.

Also, the usage context here is a case where the public key party doesn't have any way to communicate with the secret key party once the public key's been provided (e.g. through a physical medium).
I'm not yet able to understand hybrid encryption, but yesterday while trying to use libsodium I recall seeing it and concluding it wasn't fit for this; I may be wrong or misunderstanding though.

So, short question: if I were to derive a key (made for symmetrical encryption of the data) from the public key, would that same key be derivable from the private key without any additional factor?
And if as required additional factor one would need a shared salt for example, would it be considered sensitive (ie not able to be provided over by cleartext) ?

(For ref, the test implementations I tried are using libsodium's sealed boxes since both the sender and recipient are the same entity)

@brycx
Copy link
Member

brycx commented Apr 3, 2023

I'm not yet able to understand hybrid encryption, but yesterday while trying to use libsodium I recall seeing it and concluding it wasn't fit for this; I may be wrong or misunderstanding though.

I'm not sure in what way libsodium's sealed box would be unfit. Do you have a specific concern?

So, a user holds a private key, encrypts the data using this and stores it. Then, later the user should be able to decrypt it again. Is the user itself encrypting or a server (how is there two parties involved)? If there is an encryption service, then the user could simply provide their data and their public key at once, no? Then there'd be no extra communication needed, because the service encrypts it to the just-received public key.

So, short question: if I were to derive a key (made for symmetrical encryption of the data) from the public key, would that same key be derivable from the private key without any additional factor? [..]

For ECIES and HPKE you use the public key and ephemeral key pairs to compute the symmetric key. You also need some contextualization information for this part, that's where HKDF comes in. So some additional factors are used. Whether a salt should be secret or not really depends on what it is used for.

Perhaps take a look at AuthEncap() and AuthDecap() here, to get a feeling of how the shared symmetric key is derived: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1-4

If we were to provide an implementation for your use-case, it would most likely essentially be a variant of sealed box.

@Arteneko
Copy link
Author

Arteneko commented Apr 3, 2023

Okay so the use case's flows are as follows.

  • the "server" owns, in database, a collection of all encrypted payloads, all of which were encrypted using the same key (current assumption for this point on encryption)
  • when a user directly interacts with the server to send data, they trust the server to encrypt the data using the public key (still assuming)
  • a user may/will request access to their data on a later point, trusting the server to decrypt and send the requested stored data

A user may/will need an offline tool providing the same implementation for the encryption part, in which case the user would need to import the server-owned public key so the offline tool can encrypt data for later sending the pre-encrypted data to the server without need for any link during encryption.

The reference to "ephemeral session keys" makes me feel it's something made for active-link encrypted transfer between two parties, and that's what I may misunderstand.
If I were to want a sealed box kind of flow, I would then suppose that my offline client would have its own keypair acting as its sender identity; its public key being provided to the server, but then I'm lost on "what more is supposed" and "how to go from here" (ie how should such a mechanism be implemented properly, what are its limitations, and such).

If a sealed-box-like would still fill all the "offline/no-session/etc" requirements and the encryption-related issue would lie in my lack of knowledge, I'm planning to see my crypto professor/researcher at my uni for more explanations from him anyways, so I'll get more info on it too.
edit: (on the "me learning" part, soatok's newest article comes in handy now)

edit: overall, i'm gonna spend a few days digging into the topic around and such, so as this is probably out of scope for orion we may close the issue or mark it as non-bug or something to avoid cluttering. And yeah, now I see how HPKE can be used to fill this need, and if it's something welcome, then I think it would be useful to have DHKEM in the library.
Thanks a lot for your time and patience on this, I've got lots to read now and should be able to progress in the meantime!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants