nostr-protocol / nips

Nostr Implementation Possibilities
2.19k stars 517 forks source link

NIP-04 considered harmful #107

Open adiabat opened 1 year ago

adiabat commented 1 year ago

Hi - just nostr seems promising, and end to end encrypted communication is a very important part of it, but the NIP-04 spec as written should not be implemented.

There is another issue here: https://github.com/nostr-protocol/nips/issues/72 pointing out the non-uniform AES key. That issue has been closed but probably shouldn't be -- the spec still has the unhashed / truncated result of the DH as the AES key.

Another, I think more severe problem is that protocol as described uses aes-256-cbc with no message authentication. This means that messages can be undetectably altered in transit. Anyone relaying the message can change the message, and the receiver can't tell that it was changed. I would remove NIP-04 before people start trying to use it.

There are other encryption protocols that are used with the secp256k1 keys used in nostr that could be adapted for direct messages, such as BIP324 (https://github.com/bitcoin/bips/pull/1378) or lightning's bolt 8 (https://github.com/lightning/bolts/blob/master/08-transport.md). There are also ratcheting protocols which have forward secrecy like the one used by signal, but those have other trade-offs.

The BIP324 and bolt 8 protocols aren't for discrete messages; they are for encrypted & authenticated communication channels. That means it doesn't directly replace NIP-04; the bolt 4 (https://github.com/lightning/bolts/blob/master/04-onion-routing.md) onion messages would be a closer fit. But encrypted transport between nodes is also important.

The code from BIP324 and LN is available in different languages and open licenses so I think that's the best bet for getting some code that's been used and tested.

jonasschnelli commented 1 year ago

I have to agree with @adiabat here. NIP04 is potentially harmful.

However, @fiatjaf's comment on the non-uniform AES key issue seems to be a reasonable approach. There is just the risk that people start to use NIP04 with sensitive information without knowing the downsides.

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).

IMO NIP04 should at least state its infancy and thus risks of metadata exposure (who sent to who, when and how many bytes, etc.), missing message authentication (alteration by relays) and potential vulnerable crypto (no key derivation after DH). I would even go a step further and put a paragraph into NIP04 that clients implementing is, MUST warn users of the its infancy and risks.

NIP04 is probably not production ready which can lead to harm,... especially with faster adoption of nostr in general.

Of course fixing the crypto part (use AES-GCM, run HKDF after DH, etc.) is probably the trivial part (new NIP). But what needs more thinking is how much users have to trust a nostr relay and if so, could clients be force to send certain EVENTS to only relays controlled by a trusted operator (receiver himself), etc.

A more p2p-ish approach where clients connect to each other directly sound interesting at first, but seems not to be practical because not having to be "online" 24/7 is a major feature of the nostr protocol. Relays could proxy connections to avoid having to build true incoming connections to clients (with the bandwidth downside for relays).

At the end, I guess its very important to give users a clear sense of what level of security the get with DMs on nostr. ... we still use emails without PGP for a lot of important communication.

gkbrk commented 1 year ago

@adiabat wrote

This means that messages can be undetectably altered in transit. Anyone relaying the message can change the message, and the receiver can't tell that it was changed.

@jonasschnelli wrote

NIP04 should at least state its infancy and [...] missing message authentication (alteration by relays)

I want to double-check something about those warnings. Nostr events are all signed. Is it really possible to alter encrypted message content without making signature checks fail?

I know NIP-04 messages are signed by the sender's pubkey, and not the shared secret between the sender and receiver, but I don't think this would allow any relays or third parties to alter message content while keeping the signature valid.

ismyhc commented 1 year ago

I guess I could be missing something, but the content is AES encrypted with shared secret of sender/receiver. So there are only 2 keys that can read the content. Sender, receiver. No?

The Event is then signed by the sender. As long as client is validating signature of received Event, I don’t see how the content can be altered?

What am I missing?

ismyhc commented 1 year ago

@adiabat wrote

This means that messages can be undetectably altered in transit. Anyone relaying the message can change the message, and the receiver can't tell that it was changed.

@jonasschnelli wrote

NIP04 should at least state its infancy and [...] missing message authentication (alteration by relays)

I want to double-check something about those warnings. Nostr events are all signed. Is it really possible to alter encrypted message content without making signature checks fail?

I know NIP-04 messages are signed by the sender's pubkey, and not the shared secret between the sender and receiver, but I don't think this would allow any relays or third parties to alter message content while keeping the signature valid.

the content IS encrypted with shared secret.

gkbrk commented 1 year ago

Did I say anywhere that it's not encrypted by the shared secret?

ismyhc commented 1 year ago

Did I say anywhere that it's not encrypted by the shared secret?

Yeah in the bottom part of your comment. 😅

image

eskema commented 1 year ago

he's talking about the signature, not the content

ismyhc commented 1 year ago

he's talking about the signature, not the content

Ahhh... I misunderstood. Sorry @gkbrk

ismyhc commented 1 year ago

Anyways, I think maybe we are on the same page, but as I see it, the Event can be verified on the client that it's not been altered and as far as I see the encrypted content can only be decrypted by the sender/receiver as its encrypted with the shared secret from those keys.

Just trying to understand what I am missing.

gkbrk commented 1 year ago

Anyways, I think maybe we are on the same page, but as I see it, the Event can be verified on the client that it's not been altered and as far as I see the encrypted content can only be decrypted by the sender/receiver as its encrypted with the shared secret from those keys.

Just trying to understand what I am missing.

Yes, I agree with those. I don't see any way to alter the message content anywhere without being able to sign arbitrary Nostr events without having a private key. If the way we do schnorr signatures is broken, we have bigger problems anyway.

jb55 commented 1 year ago

even if nip-04 isn't broken it still sucks, either party leaking their private key and having their entire convo history public is concerning. we should be brainstorming ratchet-like specs so that if a root key is leaked you're not screwed. would be happy to sponsor anyone who wants to take on that task.

ismyhc commented 1 year ago

even if nip-04 isn't broken it still sucks, either party leaking their private key and having their entire convo history public is concerning. we should be brainstorming ratchet-like specs so that if a root key is leaked you're not screwed. would be happy to sponsor anyone who wants to take on that task.

Yup, I don't disagree here, but the original premise of the issue here seems to be misguided unless Im missing something.

Im totally fine with using another approach, but just wanted to point out that the current NIP can be used if implemented correctly and as long as each key holder doesn't leak their key 😅

adiabat commented 1 year ago

Events which encapsulate the NIP-04 messages being signed helps, and prevents the straightforward attacks, but ... why tempt fate? aes128-gcm is available pretty much wherever aes-256-cbc is, it's faster, and prevents these vulnerabilities if, for example, someone relays an encrypted message for someone else.

This may be out of scope, but for sending encrypted messages, it also feels sub-optimal that the protocol generates publicly verifiable signatures on top of all the encrypted messages it sends. Why does Alice need to prove to everyone that she's sent encrypted messages to Bob?

While hiding metadata is hard, and the perfect is the enemy of the good etc etc, there are straightforward, already implemented ways to avoid having a publicly verifiable record of all encrypted messages (including source and destination keys). If the system relies on the top level clear signing as the only way to maintain authenticity, and encryption and authentication aren't linked, it will be hard to improve metadata privacy.

fiatjaf commented 1 year ago

It is probably better to make a parallel protocol that reuses Nostr's key aspects but optimized for direct communication. It could be basically the same relay infrastructure, but the event format would be an encrypted binary blob that only the receiver would be able to read, relays would be programmed to not leak anything except to the intended receiver, senders would not be identifiable at all and receivers would only be identifiable by a temporary decoy id.

jonasschnelli commented 1 year ago

The Event is then signed by the sender. As long as client is validating signature of received Event, I don’t see how the content can be altered?

I guess this is a fair observation. While the NIP04 encryption itself is missing a MAC, the envelope signature done by the same key might provide a similar result (but again, this is cooking your own crypto scheme and should be reviewed carefully).

arik-so commented 1 year ago

This is a bit more of a high-level question, but is message authentication necessarily a desideratum? A lot of e2ee messengers don't sign the messages for the explicit purpose of plausible deniability. It might be worth considering the possibility that a potentially alterable message might actually be preferable to the alternative, should the decryption key fall into the wrong hands.

ajtowns commented 1 year ago

I think there's two components here -- one is if a stranger wants to start a direct message with you how do you notice that without being swamped by spam, and the other is maintaining a private conversation with someone you know over a public broadcast medium (which is not really any different to broadcasting over radio or similar anyway)...

For unsolicited messages from strangers, you could do a bunch of things: rate limit by requiring proof of work or an advance payment, have a foaf network and require an introduction first and just not allow messages from anyone who is too many degrees of separation away.

I think once you've done that, you can just focus on the second part -- I have a pubkey A, you have a pubkey B, we both know those things, and both of us want to communicate via a (semi-trusted?) relay R without anyone else knowing what we're saying, how much / how often we're saying things, possibly that we're communicating at all, or being able to confirm after the fact when A or B's private keys have been obtained, that any particular thing was communicated?

That is, I think you want (at least) two event kinds -- an introduction event that you can listen for to see if strangers want to talk to you, and the actual direct messages that can focus more on privacy, and could have single-use pubkeys and lossy filters to make it hard for even the relay you're using to do traffic analysis.

NIP 4 makes it easy to see who's talking to each other, how often/much they're talking, and lets anyone who compromises the keys later see past history. Might be worth updating the NIP to make it clear that it's a prototype and is known to have those flaws?

lucash-dev commented 1 year ago

I think once you've done that, you can just focus on the second part -- I have a pubkey A, you have a pubkey B, we both know those things, and both of us want to communicate via a (semi-trusted?) relay R without anyone else knowing what we're saying, how much / how often we're saying things, possibly that we're communicating at all, or being able to confirm after the fact when A or B's private keys have been obtained, that any particular thing was communicated?

Some two years ago I was working on a simple protocol (not completely sure it's original, you guys probably might tell) that looks useful as the second part -- it was based on a public database that stores values indexed by public keys. I had no idea anyone was going to implement such a database (Nostr relays seem to be an implementation of such databases).

Basic idea is:

  1. Alice and Bob have a shared secret S1 (by whatever shared secret generation scheme).
  2. Alice and Bob both derive the same public/private key pair P1 from S1.
  3. Alice generates a second secret S2 (or both Alice and Bob might have generated multiple secrets from the start).
  4. Alice posts publicly a message M1 (Nostr note in this case) encrypted symmetrically (using S1 as key), and use P1 as the public key of the "user". The message includes info for Bob to generate S2, and a payload.
  5. Bob queries relay for messages that matches the public key P1.
  6. Bob decrypts M1, and obtains the payload and S2.
  7. Bob restarts the process from (1), using the new secret S2 as the shared secret.

As long as one of Alice or Bob interacts with the relay in a perfectly anonymous way (eg using Tor and with no authentication), the two ends of the communication can't be matched. With fixed rate decoy messages and queries, it becomes impossible to know when/how much each end is communicating.

Messages in each sequence can't be linked to one another unless the secrets are leaked.

If any of the secrets is leaked, you still can't say who wrote the messages, much less prove it. The secrets aren't linked to identities.

It's impossible for the relay to censor any specific exchange without stopping all communications of that type within the relay.

There are many other possible ways to implement it, but the fact that Nostr lets you query relays by public key makes a shared sequence of throw-away key pairs the obvious choice.

Please note this would still be secure and censorship-resistant (in the sense of not being possible to censor specific exchanges) even with just one relay available. The relay has also plausible deniability as they have no idea what's being sent (basically like a router in an ISP). For further reduction of legal liability, messages could be dropped after a fixed TTL.

Could also use "remailers" within this protocol to further enhance privacy. The remailer could either use this new scheme or just plain old NIP4, receiving an event encrypted, then posting it. Chaining multiple remailers means network analysis can't work as long as at least one remailer doesn't collude with the relay. This can remove the dependency on Tor (but needs new infra-structure).

I think that's actually a better use-case for Nostr relays than public messages (which isn't censorship resistant in any strong sense, likely in any practical sense at all).

xz-cn commented 1 year ago

Events which encapsulate the NIP-04 messages being signed helps, and prevents the straightforward attacks, but ... why tempt fate? aes128-gcm is available pretty much wherever aes-256-cbc is, it's faster, and prevents these vulnerabilities if, for example, someone relays an encrypted message for someone else.

Using a library such as aes-gcm is indeed a better choice than the current aes-cbd scheme as the MAC part has been taken care of.

If the key is based on Curve25519, you can use the mature TweetNaCl library's authenticated encryption for end-to-end encrypted communication.

paulmillr commented 1 year ago

noble-secp author here. just want to provide some information:

  1. Topicstarter is right: nip04 is harmful
  2. aes-cbc also needs padding, and bad padding can be pretty bad.
  3. aes-gcm-128 is not a future-proof option. Use at least aes-gcm-256 or even better: xchacha20-poly1305.
  4. curve25519 (@xz-cn) is not cool because: 1) it needs a separate elliptic curve, which can be pretty big if written from scratch 2)

Ideally: secp256k1 (perhaps x-only ECDH) + HKDF + XChaCha20-Poly1305; will still need an audit and comparison to protocols like the one Signal is using. It's important to not implement just anything from scratch without consensus first.

At least, if you deploy something like this, make it versionable. If protocol gets broken, you'll at least be able to upgrade it.

mikedilger commented 1 year ago

I think that crypto is about right. I pointed out the lack of an HKDF a while back.

As for protocol versioning, if the crypto is ever broken we can just create a new event kind with a new form of DM. In fact, that is what we have to do if we were to make changes, because NIP-04 is implemented in many places we can't go changing it now. So a new DM spec would be a new event kind.

BUT, I'm not in favor of DMs over nostr. I'm in favor of advertising an endpoint in your metadata, and using out-of-band messaging.

xz-cn commented 1 year ago

I think that crypto is about right. I pointed out the lack of an HKDF a while back.

As for protocol versioning, if the crypto is ever broken we can just create a new event kind with a new form of DM. In fact, that is what we have to do if we were to make changes, because NIP-04 is implemented in many places we can't go changing it now. So a new DM spec would be a new event kind.

BUT, I'm not in favor of DMs over nostr. I'm in favor of advertising an endpoint in your metadata, and using out-of-band messaging.

In that case, you will need external support for the DM function... I guess that is not the idea of the Nostr protocol.

What we can do is indeed to add a new type of event. Which not only makes the messaging part safer, but also includes the protection of the DM metadata. In that case, other people won't know to whom you have DMed and when. I understand there is a repo working on this already? https://github.com/SebastiaanWouters/emon

mikedilger commented 1 year ago

I think @jb55 https://github.com/nostr-protocol/nips/issues/107#issuecomment-1363215100 and @fiatjaf https://github.com/nostr-protocol/nips/issues/107#issuecomment-1363261759 made very good points, and @paulmillr https://github.com/nostr-protocol/nips/issues/107#issuecomment-1426854522 on the crypto. I offer my concurrence with them and as I won't be leading this effort, I have nothing else to offer so I'll bow out of this issue. I look forward to one day a new way to do DMs more securely.

earonesty commented 1 year ago
  1. with the signature, the need for a mac isn't really present - message is already tamper proof, gcm is fine tho.
  2. versioning is key
  3. the dm-spec, as is, leaks no more public keys than are already leaked in the existing protocol, fixing that is a separate issue
  4. doing dm's "more securely" is challenging. leaking the main key, even with discarded channel keys, results in a full loss of metadata privacy. and most clients would keep channel keys for a long enough time that the additional security isn't notable. only decent way is to establish a more "direct" connection with a DM, then at least you have pure deniability. which, of course, you can use nip-4 style shared secret to establish.
  5. i think "considering it harmful" isn't really considering what its intended use case is: "persistent censorship resistant e2e encrypted messages". if you don't like the persistence (which can always leads to metadata leakage), don't use nostr
  6. any "dm" system should probably be layered on nip-4 shared secret as the initial channel creator anyway. maybe just change nip-4 wording to say "don't use this for dm's... use it at a lower layer in a secure dm system"
braydonf commented 1 year ago

@ajtowns I was thinking something similar in regards to two events kinds, a request and then messages.

@lucash-dev I had a similar thought, looking for messages at an agreed upon shared secret "location".

Event Kind A:

A request for Direct Message. To prevent spam there is either a NIP-57 private payment, proof-of-work, or is a known existing pubkey that is followed. For example a Diffie-Hellman key exchange can be made for all pubkeys that are followed to be "locations" to watch for incoming messages.

Event Kind B:

After confirming the Event Kind A, messages are sent using Event Kind B. The identities of the messages are not known and encrypted. How each party knows where to find the messages is based on information exchanged in Event Kind A. The messages do not need to stay on relays until after they have been received, or in the case that both are online they can be sent directly peer-to-peer. Read receipts can be optional for confirming the delivery.

lucash-dev commented 1 year ago

@ajtowns I was thinking something similar in regards to two events kinds, a request and then messages.

@lucash-dev I had a similar thought, looking for messages at an agreed upon shared secret "location".

Event Kind A:

A request for Direct Message. To prevent spam there is either a NIP-57 private payment, proof-of-work, or is a known existing pubkey that is followed. For example a Diffie-Hellman key exchange can be made for all pubkeys that are followed to be "locations" to watch for incoming messages.

Event Kind B:

After confirming the Event Kind A, messages are sent using Event Kind B. The identities of the messages are not known and encrypted. How each party knows where to find the messages is based on information exchanged in Event Kind A. The messages do not need to stay on relays until after they have been received, or in the case that both are online they can be sent directly peer-to-peer. Read receipts can be optional for confirming the delivery.

Precisely. I think much of the details could be just copied from existing protocols, eg based on Double Ratchet like Signal. The only thing that needs to be "invented" is the generation of the "location", which might be as trivial as using DH, hashing the result, and using that as a private key for the "author" of the new events, then with each new secret generated just using its hash as a private key.

However, I'm also intrigued by the possibility of using "private zaps" (receipts of LN payments with encrypted data) for encrypted direct messages. By the pace of development it might be ready well before a good replacement for NIP-4 is figured out.

Maybe both might be combined, with a "private zap" used as Kind A to jump start the protocol.

braydonf commented 1 year ago

Yeah, Private Zaps for Kind A to jump start sounds useful.

The location could be a DH location, seems simple. Could be useful to implement to see how it might work in practice.

Those locations could also be shared among many recepients that might not be involved. AES-GSM could be used to determine which messages can be decrypted and intended for the recepient (this would have some additional CPU and bandwidth cost for stored messages at-least). Peer-to-peer would then optimize bandwidth and CPU usage. Specific relays should likely also be part of the defined location from Kind A.

Want to look more into Double Ratchet and how Signal is working with groups.

lucash-dev commented 1 year ago

Simplest incrementally better thing would be to just take pretty much exactly NIP-4, but derive properly three keys from the DH (using prefixed hashes):

then send it as a nip-4 event. it would look like just a regular nip4 thing and relays don't need to be aware of anything different.

(might use each of the "fake" keys for one of the users, just to make it easier for clients as it is closer to nip4, though it leaks a bit more info).

clients need only know what public keys to use for DH (maybe just everybody you follow) and request them from relays.

disadvantages:

much easier to implement than a proper private messaging protocol though. however, like I said, by the time anyone has time to do it, a usable alternative might already be available.

braydonf commented 1 year ago

still leaks when a specific "location" (pair of "fake" author/recipient keys) is used

It's association would only be known to the two parties though (mostly).

users have to always use same location for talking to same people

The "location" could be random after the initial DH exchange (e.g Event Kind A).

relays can still figure out which users are talking to each other by connections and requests for the location

This is where being able to use short location queries could be useful. Let's take for example, if the full location was 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d. It could be possible to query it by using only the leading bytes, for example 3b. If there were too many results, 3bf0 could be used and so forth.

lucash-dev commented 1 year ago

The "location" could be random after the initial DH exchange (e.g Event Kind A).

Yes, but that’s harder to specify and implement.

I was just trying to spell out the a solution that would require the minimum effort to implement. You could do the above client-side only, and basically just tell your client to follow some weird keys and add some transformation when displaying DMs from those keys and sending to them.

lucash-dev commented 1 year ago

Thinking a bit more and maybe having a separate “fake” sender (and querying by key prefix) is actually worse in terms of leaking info to relays (though it makes it better in terms of public metadata)

If you use your actual key as sender — but a “fake” key as receiver — the relay can’t tell who among your followers is the recipient. While your recipient querying by public key prefix and the relay matching it to what keys you’re using to publish would likely reveal to the relay both ends of the communication.

And you can always send some “decoy” messages to hide when exactly you’re actually communicating privately with anyone.

if you’re trying to talk to people you don’t publicly follow, and don’t want anyone to know the fact you’re in any way connected to them — then you’d need a fake sender too.

but perhaps hiding metadata from your relay is too much. Right now most clients just assume relays are 100% trusted anyway.

fyookball commented 1 year ago

Great thread, even though I don't understand all the cryptography.

@lucash-dev your idea to have a shared secret and then use it to create a "third party" sender is very interesting. As I see it, the problem is, if that shared secret is generated by the typical ECDH exchange (which is most practical), then if Alice's private key is leaked, they may find her shared secret with Bob based on the fact she may have had previous public interaction with Bob.

One very simple idea I would like to share is the following, maybe someone aleady suggested something similar:

Alice wants to initiate a private encrypted conversation with Bob. They commonly interact with keys A1 and B1. They use the following protocol: Alice creates key A2, and sends ECDH transmission to B1, with instructions that he should contact her at A3. Bob creates B2 and continues to send ECDH encrypted chat to A3. All the public sees is that Bob got a random encrypted message from some unknown person. Also, in this scheme, A2, A3, etc should not be deterministic from A1. They are randomly generated semi ephemeral keys to be stored on client.

braydonf commented 1 year ago

A few resources in reference to mentioned Double Rachet Algorithm and related:

lucash-dev commented 1 year ago

@fyookball that's kinda what we were talking about before.

you're right about the consequences of leaking one of the two private keys. we probably want something better than that as a "permanent solution".

my idea of simply generating a "fake receiver" is more of an attempt of putting together a minimal effort solution that would remove some significant metadata from the event.

I don't have much time to implement anything, so I was kinda hoping someone would just do a quick fork of some client (Damus please?) and add the minimal version of the idea. maybe I'll write it in the future, but likely it will already be solved by the time I have bandwidth :)

fyookball commented 1 year ago

@lucash-dev Cool. But before the additional "handshake stuff" is built, we should probably address the cryptographic issues mentioned. https://github.com/nostr-protocol/nips/issues/72#issue-1452982867 seems to be a decent prescription. I agree that is a good way forward, and wouldn't mind working on an implemention if that is the direction.

fyookball commented 1 year ago

I put together a quick POC based on the suggestions to use HKDF and aes-256-gcm. https://github.com/Electron-Cash/Nostron/blob/nip04research/nip04research/EncryptedMessaging.py

Disclaimer: I'm not a cryptographer.

braydonf commented 1 year ago

FWIW: There is also discussion of building upon Signal protocol/specifications by @fiatjaf on Nostr. SimpleX and some others were mentioned.

See note: @note1rqsp4klhk7k5nkq02jnje7zeh30ju4wlth27v69x4xmweh9vesmqgczdya

mikestaub commented 1 year ago

@jb55 please team up with the Bluesky team as they need to solve the same problem and it makes no sense to duplicate efforts on a commodity feature. https://github.com/bluesky-social/atproto For something as serious as this I would not start from scratch but rather partner with the https://github.com/threema-ch/threema-web or https://github.com/wireapp/wire teams. This is not a trivial thing to implement safely.

paulmillr commented 1 year ago

@mikestaub

please team up with the Bluesky team

Why are you coming here with proprietary bullshit created by pro-censorship people?

I just visited their website. The app is invite-based. = NOT OPEN. Closed-source. = NOT OPEN.

paulmillr commented 1 year ago

Excuse my aggressive reaction, but it's completely reasonable. It's not nostr community who needs to contact Bluesky. It's the other way.

For those who don't know, at least some of old Twitter execs are behind Bluesky. The people actively supported censorship in various forms; something I believe nostr is fighting against.

They were spending $ doing nothing for 3 years. Then there were a bunch of announcements of announcements.

Then they've opened-up, but using invitation system - which is a growth hack to make people want "in". Shady. The app is closed-source. The development process is not even close to public participation as nostr.

I believe Bluesky is playing a game where they'll pivot to completely centralized protocol in the end. Same as OpenAI, which isn't "open" at all right now.

mikestaub commented 1 year ago

@paulmillr your response is well-founded, reasonable, and fair. I had the exact same response when it was announced. I am confident though after talking with the team that their ultimate vision is well-aligned with nostr, they are just taking a different path to get there. I have asked the team to engage the nostr community on this issue.

earonesty commented 1 year ago

there's a simple thing that should be done with nip04

we should hash the shared secret, and probably use an ephemeral public/private key pair (so the sender can't read the message after it's sent). this is simple stuff (standard ECIES)

to get rid of any residual structure that's the normal thing you do with shared secrets before you start encrypting things with AES

question:

indeed i can send bitcoin to anyone with a npub as well

this is not bluesky

if this is OK for anyone i'll open up a PR to nostr-tools

my only question is:

arthurfranca commented 1 year ago

lets not go all astronaut and try to solve things that nostr is not trying to solve (deniability, etc.). nip04 messages are fine [...] this is not bluesky

agree 👏️💯️

[...] so the sender can't read the message after it's sent [...]

what?

earonesty commented 1 year ago

lets not go all astronaut and try to solve things that nostr is not trying to solve (deniability, etc.). nip04 messages are fine [...] this is not bluesky

agree 👏️💯️

[...] so the sender can't read the message after it's sent [...]

what?

when encrypting for someone using ec, you can do it two ways:

using their public and your private (not standard) using their public and an ephemeral private (standard ecies)

the advantage of the latter is that if i throw away the ephemeral key, there's no way i can decrypt the message. only the recipient can. this may not seem like a big deal, but it means there's one less key that can be compromised, at no loss of functionality. only the recipient has to custody his key carefully, the sender can leak his private key, and the recipient is still safe

there are benefits to both. for example, i can post a message that is a contract between two people, and either person can access the contract at any time. this is not a "direct message", and this could use a nip4 style encryption with intention (both parties can access)

moving to a more standard format (ephemeral pub/priv + hashed ecdh) will at least make the protocol correct under the claim that it's a good way of sending a message when you don't care if anyone knows that you did.

i can see a need for both actually (shared-access vs direct message). but in both cases, we should to hash the shared secret to eliminate structure before using as an aes key.

again: perfectly happy to make a protocol that handles these cases, and the big question is still: in-place edit of NIP4, or introduce new kind(s) for the hashed/ecies + more standard encryption

nip4, as it stands is a "symmetric encrypted message" not a "direct message" since there's no directionality. and the use of the raw shared secret as the key is generally frowned upon (probably ok, especially with a 16-byte random iv though)

arthurfranca commented 1 year ago

Thanks for explaining, got the benefit of using the "direct message" encryption.

"Shared-access" type is needed to keep a regular chat between two people, that's why I found a suggestion to not have this feature available strange.

[...] hashed/ecies + more standard encryption [...] we should hash the shared secret [...] to get rid of any residual structure

I have no ideia about it xD

paulmillr commented 1 year ago

@earonesty if bob uses ephemeral key to send msg to alice, how would alice authenticate bob?

earonesty commented 1 year ago

all nostr events are signed. we don't have a mac/auth issue. content currently is just iv+data. we change it to version+epub+iv+data and we're good

fyookball commented 1 year ago

Was thinking to make a new NIP for new encrypted format...saving all the ephemeral stuff for another time, just an upgraded version of NIP-04 based on community suggestions. Does anyone have any feedback on this PoC implementation: https://github.com/Electron-Cash/Nostron/blob/nip04research/nip04research/EncryptedMessaging.py

This does the hash, salt and HKDF.

Thinking to do new NIP on my new client https://OstrichGram.com

If there's a good way to add various kinds of encryption (or version field) let me know but I think it should be simple.

earonesty commented 1 year ago

imo, salt isn't needed, just a hash is fine on the shared secret. if you insist on hkdf salt, re-use the iv - there is zero argument for this unless hashing is broken. get_shared_key is not for dm's we should use an ephemeral key... only argument should be the public key of the recipient:

encrypt(message, pubkey)

specifically sha3 is not a conjectural hash, it's proven. so the arguments for hkdf are nil (https://crypto.stackexchange.com/questions/40406/choosing-between-simple-hash-and-hkdf-to-derive-the-second-key-used-for-mac)

paulmillr commented 1 year ago

@earonesty are you saying hkdf isn't needed at all, for other cases?