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

nip-04 key material not uniformly random #72

Closed
mikedilger opened this issue Nov 17, 2022 · 8 comments
Closed

nip-04 key material not uniformly random #72

mikedilger opened this issue Nov 17, 2022 · 8 comments

Comments

@mikedilger
Copy link
Contributor

mikedilger commented Nov 17, 2022

Encrypted messages are encrypted according to nip-04 using a Diffie-Hellman shared secret generated from a private key and a public key. This shared secret is then used as an AES key. But such a shared secret is not uniformly random. AES requires a uniformly random key to guarantee its level of security. Cryptographers recommend using an HKDF (HMAC-based extract and expand key derivation function) ideally with a salt in order to get a uniformly random key suitable for symmetric encryption by, e.g. AES. SHA256 can be used as the HKDF.

I would suggest generating a random salt, SHA256 the shared secret and the salt together, and include the salt with the message in the same way that the IV is included with the message. Alternatively, ditch the salt entirely. Or it can be a fixed well-known string.

Lest you mistake me for a cryptographer (albeit I did take a crypto class from Phil Rogaway in the early 1990s), I'm getting my information from this page: https://docs.rs/elliptic-curve/latest/elliptic_curve/ecdh/struct.SharedSecret.html

I'll leave it to others to suggest how to move forward. IMHO event kind 4 should not change but should be superseded.

@fiatjaf
Copy link
Member

fiatjaf commented Nov 17, 2022

I did ask at least one cryptographer before writing the spec for NIP-04 if it was ok to use the shared key directly without hashing it first and he said it was ok.

But even if this is super bad I agree we shouldn't change NIP-04.

By the way NIP-04 was never supposed to be the thing in the first place, it was made as a prototype to show it was possible and expecting someone to supersede it with a better protocol (I personally think we must still find some other more p2p more private way to send direct messages between Nostr contacts that doesn't involve broadcasting to relays).

@mikedilger
Copy link
Contributor Author

It's encrypted either way. The HKDF just makes it less susceptible to cryptanalysis.

p2p encrypted messaging would avoid public knowledge of who was talking to who (would hide the metadata) but requires both parties online at the same time and at least one able to listen. Many clients can't listen due to corporate networks, home firewalls, CGNAT, etc. I was thinking maybe having messages both encrypted and ephemeral. Clients who would invite encrypted messaging could publish an event disclosing their IP address, without any intent as to who they might want to talk to. As long as enough of them did, it wouldn't be clear who among them might be talking to whom.

@Welteam
Copy link

Welteam commented Dec 15, 2022

Reading NIP-04, I was wondering why you would use both keys to generate a shared secret. Isn't sending the message encrypted with the recipient public key enough? If the point is to ensure both sender and recipient can decrypt the message, you could specify clients must encrypt the message for both using the S/MIME way (generate a symmetric key, encrypt the message with it, encrypt the symmetric key with all recipients' public key).
Did I miss an obvious issue with this?

@fiatjaf
Copy link
Member

fiatjaf commented Dec 15, 2022

@Welteam I don't know if that encryption with the other person's private key is even possible using these elliptic curves, but even if it is it would be less efficient in multiple ways. What is the advantage you see there?

@mikedilger
Copy link
Contributor Author

With more than two parties, @Welteam suggestion is the only way to go. With just two parties, I think ECDH (elliptic curve Diffie-Hellman, which is what NIP-04 is doing even if not stated explicitly as such) is more efficient and straightforward. My 2c.

@fiatjaf
Copy link
Member

fiatjaf commented Dec 15, 2022

I think for multiple parties it can be something like

  1. Alice writes message
  2. Alice generates a random secret x
  3. Alice encrypts message with x using AES-CBC
  4. Alice generates shared secrets aB, aC and aD for Bob, Carol and Daniel respectfully.
  5. Alice encrypts x with aB, aC and aD
  6. Alice publishes an event containing all the encrypted xs and the encrypted message
  7. Now both Bob, Carol and Daniel can decrypt x using the their shared key with Alice, and from that decrypt message using x

But I'd rather not make this at all and instead tell Alice, Bob, Carol and Daniel to use a private relay.

@mikedilger
Copy link
Contributor Author

mikedilger commented Dec 16, 2022

I'm all for people advertising their availability for private chat at url=x, protocol=y, and then having truly private chat without a relay snooping on their metadata.

@fiatjaf
Copy link
Member

fiatjaf commented Dec 20, 2022

Closing this since it has derailed through multiple other subjects already.

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

3 participants