Giter Site home page Giter Site logo

Comments (55)

csuwildcat avatar csuwildcat commented on August 20, 2024 5

Eating-Popcorn-Soda.gif

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024 4

I like the idea behind it, but that would mean a limited number of keys to begin with since they would all have to be generated before A' could be used.

What about GPG's concept of subkeys and revocation certificates? Create a primary key pair that is only used for creating and revoking subkeys. Use the subkeys for signing all messages. If one gets compromised, publish a revocation certificate and create a new subkey. Reputation remains entact.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024 3

What happens if I lose my private key or it gets leaked? is definitely the major obstacle for a moderately technical user here. An average user is going to have trouble even understanding an immutable private key vs a password they can update whenever they want. I suspect the concern for both types of users will typically be solved by a service abstracting away those details and allowing users to register accounts and post just like they do with the prominent social networks.

But it would still be great to solve for the problem of an exposed private key.

from nostr.

fiatjaf avatar fiatjaf commented on August 20, 2024 1

Disregarding the irony of posting a Twitter link here, here's the idea I have in my mind for a "key revocation" scheme that would work (although it requires the user to still have a "master key" saved somewhere): https://twitter.com/fiatjaf/status/1479608941197893635

More discussion on https://t.me/nostr_protocol/9790

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024 1

I think there's something to your point about social attestation and web of trust. That's ultimately the most resilient, scalable solution to verified identity, even before we get to the problem of revoking and issuing new keys. That's how it works in meatspace, anyway. The people I trust confirmed that this person is who they say they are.

I can imagine the need for 2 new NIPs.

The first new NIP would provide a mechanism for someone to vouch for another person's pubkey/username combo (both properties are important). The OpenPGP trust model might be instructive for us here, both in terms of the way public key/user ID combos are endorsed by other trusted keys and the number of first-hand or second-hand endorsements that are required to consider a key trusted. Vouch events should be NIP-03 timestamped, perhaps even with some NIP-13 proof of work to make them at least a little costly. This NIP would be valuable on its own, providing decentralized verification that a key is who they say they are without relying on any authority outside the nostr network.

The second NIP would provide a mechanism for publishing a key revocation and optionally issuing a new one. These should be NIP-03 timestamped as well, and again, perhaps require some NIP-13 proof of work. For followers of the revoked key, clients should add the new key to the contact list. It might be a good idea for clients to display some sort of warning on events published by the revoked key after it was revoked, and to display an "awaiting proof of identity" warning on the new key until the requisite number of vouch events are published. Once the threshold is met, the client should reject all new events published by the revoked key and make it clear that the old and new keys constitute the continuation of a single identity.

We've already got NIP-05 which lets people validate their keys based on their web address. Might be good to have another one or more NIPs that let people validate their keys based on their social identities (essentially formalizing what https://www.nostr.directory is doing). With these plus the 2 new NIPs outlined above, we'd have several paths to identity verification with varying degrees of anonymity. These methods would provide users on the network confidence that the purported identity of the keys is valid.

Thoughts @fiatjaf @catleeball @scsibug @A60AB5450353F40E?

from nostr.

alvistar avatar alvistar commented on August 20, 2024 1

Hi, everybody, I just read about Nostr protocol from Twitter messages and went reading immediately the specs.

I immediately saw issues in just using pub key as identities because this is static, as already posted above.

I do suggest to have a look at decentralized identifiers did - https://www.w3.org/TR/did-core/

To look at some promising implementation look for ION - https://github.com/decentralized-identity/ion

And guess what, that”s the same used by https://developer.tbd.website/projects/web5/

anyway, the idea would be including the did in the event instead of the pub key.
Then relay should resolve the did, check which is the current valid pub key for signing and verify the signature.

I was short in writing, but I’ll be glad to reply I’d something is not clear.

from nostr.

fiatjaf avatar fiatjaf commented on August 20, 2024 1

If clients and relays had to support the full range of DIDs they would be so bloated no one would have ever written any. Even if they only supported the ION scheme that would still be basically impossible unless (I imagine) we used their JavaScript libraries that talk to a central server.

Also it is not a settled matter that ION works as advertised.

You can already say Nostr is using DIDs, if a bare public key is a DID. Nothing prevents you from calling your Nostr public key a did:bip340:<key> or something like that.

from nostr.

alvistar avatar alvistar commented on August 20, 2024 1

If clients and relays had to support the full range of DIDs they would be so bloated no one would have ever written any. Even if they only supported the ION scheme that would still be basically impossible unless (I imagine) we used their JavaScript libraries that talk to a central server.

Also it is not a settled matter that ION works as advertised.

You can already say Nostr is using DIDs, if a bare public key is a DID. Nothing prevents you from calling your Nostr public key a did:bip340:<key> or something like that.

Hi,
this problem has been already risen by web browser company. And the simple way of resolving it is:

https://github.com/decentralized-identity/universal-resolver

Actually this should be external from clients, relays. All you need to implement is single API call to resolve DID to pubkey. That's it. You should not care about details of DID methods.

As analogy thinks about how you resolve a URL to ip address via DNS. You are not implementing DNS Server inside your app.

Regarding ION, that's true. It still need to be more deployed to check if it fulfills its promises. Anyway it's the DID method I found more scalable and with more adoption so far.

And yes, if you instead of just putting pub key, a method is used like did:key: you are already using DIDs. As simple as that.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024 1

DIDs seem to be a more stable solution in the long run. The idea is to "outsource" the key management to DID managers. By using DIDs the protocol opens itself up to a lot of new key management schemas. People can activate, deactivate keys as they wish, create multisig controllers, x509 PKDs, etc.

To avoid coding a universal resolver, create a NIP to specify a subset of DID methods (start with just one) accepted by the nostr community. As more DID tooling becomes available new methods can be added.

DIDs are a more interesting solution to verification than the current NIP05, since NIP05 requires a trusted DNS+HTTPS protocol.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024 1

Crazy idea: why not simply create a new event type where the content is a DID Document and a DID:NOSTR:ID resolver that points to that nostr DID Document? In that way, there are no external DID resolvers to implement/cache and we solve the key rotation problem by adding and removing keys inside the DID Document.

It would be an evolution of NIP-26, allowing multiple keys and behavior types.

This can have use cases even outside nostr with a full-blown did method that accesses a key through a nostr relay.

So, a master key with 2 devices is represented as:

{
  "id": "did:nostr:<id>",
  "verificationMethod": [
    {
      "id": "did:nostr:<id>#key-0",
      "type": "JsonWebKey2020",
      "controller": "did:nostr:<id>",
      "publicKeyJwk": {
        "kty": "OKP",
        "crv": "Ed25519",
        "x": "0-e2i2_Ua1S5HbTYnVB0lj2Z2ytXu2-tYmDFf8f5NjU"
      }
    },
    {
      "id": "did:nostr:<id>#key-1",
      "type": "JsonWebKey2020",
      "controller": "did:nostr:<id>",
      "publicKeyJwk": {
        "kty": "OKP",
        "crv": "X25519",
        "x": "9GXjPGGvmRq9F6Ng5dQQ_s31mfhxrcNZxRGONrmH30k"
      }
    },
    {
      "id": "did:nostr:<id>#key-2",
      "type": "JsonWebKey2020",
      "controller": "did:nostr:<id>",
      "publicKeyJwk": {
        "kty": "EC",
        "crv": "P-256",
        "x": "38M1FDts7Oea7urmseiugGW7tWc3mLpJh6rKe7xINZ8",
        "y": "nDQW6XZ7b_u2Sy9slofYLlG03sOEoug3I0aAPQ0exs4"
      }
    }
  ],
  "authentication": [
    "did:nostr:<id>#key-0"
  ],
  "assertionMethod": [
    "did:nostr:<id>#key-1",
    "did:nostr:<id>#key-2"
  ]
}

Which encoded becomes:

{
  "id": <id>
  "pubkey": "did:nostr:<id>#key-0",
  "kind": 666,
  "created_at": 1671551112
  "content": "{ \"id\": \"did:nostr:<id>\", \"verificationMethod\": [ { \"id\": \"did:nostr:<id>#key-0\", \"type\": \"JsonWebKey2020\", \"controller\": \"did:nostr:<id>\", \"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"0-e2i2_Ua1S5HbTYnVB0lj2Z2ytXu2-tYmDFf8f5NjU\" } }, { \"id\": \"did:nostr:<id>#key-1\", \"type\": \"JsonWebKey2020\", \"controller\": \"did:nostr:<id>\", \"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"X25519\",\"x\": \"9GXjPGGvmRq9F6Ng5dQQ_s31mfhxrcNZxRGONrmH30k\" } }, { \"id\": \"did:nostr:<id>#key-2\", \"type\": \"JsonWebKey2020\", \"controller\": \"did:nostr:<id>\", \"publicKeyJwk\": {\"kty\": \"EC\",\"crv\": \"P-256\",\"x\": \"38M1FDts7Oea7urmseiugGW7tWc3mLpJh6rKe7xINZ8\",\"y\": \"nDQW6XZ7b_u2Sy9slofYLlG03sOEoug3I0aAPQ0exs4\" } } ], \"authentication\": [ \"did:nostr:<id>#key-0\" ], \"assertionMethod\": [ \"did:nostr:<id>#key-1\", \"did:nostr:<id>#key-2\" ]}"
  ...
}

And after posting that, users can use did:nostr:<id>#key-1, did:nostr:<id>#key-2 to represent did:nostr:<id>#key-0

To modify and remove a key (key-2), just tag the previous one:

{
  "id": <newId>
  "pubkey": "did:nostr:<id>#key-0",
  "kind": 666,
  "created_at": 1671551113
  "tags": ["e", <id>] 
  "content": "{ \"id\": \"did:nostr:<id>\", \"verificationMethod\": [ { \"id\": \"did:nostr:<id>#key-0\", \"type\": \"JsonWebKey2020\", \"controller\": \"did:nostr:<id>\", \"publicKeyJwk\": { \"kty\": \"OKP\", \"crv\": \"Ed25519\", \"x\": \"0-e2i2_Ua1S5HbTYnVB0lj2Z2ytXu2-tYmDFf8f5NjU\" } }, { \"id\": \"did:nostr:<id>#key-1\", \"type\": \"JsonWebKey2020\", \"controller\": \"did:nostr:<id>\", \"publicKeyJwk\": { \"kty\": \"OKP\", \"crv\": \"X25519\", \"x\": \"9GXjPGGvmRq9F6Ng5dQQ_s31mfhxrcNZxRGONrmH30k\" } } ], \"authentication\": [ \"did:nostr:<id>#key-0\" ], \"assertionMethod\": [ \"did:nostr:<id>#key-1\" ] }"
  ...
}

Created at guarantees the order of key changes.

from nostr.

csuwildcat avatar csuwildcat commented on August 20, 2024 1

@alvistar it's nice to see other proponents of DIDs and related technologies showing up in places like this. I don't want to speak on this group's project to maintain a level of respect I hope they'll reciprocate (past interactions haven't been great). Our work at Block on Web5 is going well, let's catch up on a different medium about it.

from nostr.

fiatjaf avatar fiatjaf commented on August 20, 2024

These are open questions. Any input is appreciated.

What do you mean by "distributed"? In my mind it will be primarily a manual process of talking to people etc. But there are some tricks that can be done.

What do you mean by key rotation? Keys are not meant to be rotated, what is the reasoning for wanting that?

For lost keys there are some ideas of making a best-effort transition to a new pubkey by notifying followers, but this is a somewhat impossible problem no matter how you tackle it. Somehow, somewhere, some keys must be kept safe. If you lose everything you lost everything. Right?

from nostr.

scsibug avatar scsibug commented on August 20, 2024

I was thinking about whether we needed an event type to signal key rotation had occurred. Giving guidance for client behavior is a bit tricky though. Should clients auto-switch following the new key and un-follow the old one? Should they accept any future events from the previous key?

I think the main use case is key compromise. If that happens, someone could use that key to publish an earlier (timestamped) event that rotated the key to one they controlled, so having clients do anything automatically in response to a compromised account isn't smart.

Perhaps the safest option is to have an event type that signals the account is compromised, or should no longer be trusted. Regardless of the timestamp, that should be a signal to clients to consider the pubkey compromised - that means any past or future dated events may be exposed, and any direct messages should be considered exposed as well.

There would have to be an exception to the deletion NIP-09 event kind, since you don't want the attacker issuing a delete against the "compromised pubkey" event.

My vote would be (eventually) having a "key compromise" event that clients (implementing the NIP) would use to visually alert the end user, and perhaps even do things like prevent DMs from being sent.

from nostr.

fiatjaf avatar fiatjaf commented on August 20, 2024

But yes, for users that will not be able to store their keys safely I think there is no solution except trusting those keys to someone else.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Quoting that tweet thread here for posterity in case those links ever 404:

What about this as a means of simultaneously revoking a compromised key and unambiguously telling everybody to jump to a new one?

If the idea is good credits to
@SomsenRuben, otherwise to me.

@pavolrusnak @EricSirion @takinbrrrr (because you commented on my previous question)

  1. Generate a sequence ABCD... of keypairs
  2. Generate a sequence A'B'C'D'... of keypairs such that A' = tweak(A, B'), B' = tweak(B, C') and so on — using http://bips.xyz/341 key tweaking functions (only replacing the taproot script hashes with the pubkeys in this case)
  3. Start using A' as a public identity
  4. if A' is compromised publish a proof that B' is contained inside A' (via the tweak) which will imply that B is the next key
  5. Start using B'

I'm not sure what this proof would look like? Just publishing A and B' perhaps? That would allow anyone to verify that tweak(A, B') = A, which should be enough, right?

from nostr.

A60AB5450353F40E avatar A60AB5450353F40E commented on August 20, 2024

This might be of interest: https://github.com/bitjson/chip-bcmr

It requires a blockchain for timestamping so order of events cannot be forged, but is basically an off-chain convention for identity management.

An "authchain" is a chain of signatures where each key signs for the next key in the chain (or sign for the same key again) + some metadata. Only the latest key is considered the identity's key, and signatures (using old keys) published after authhead has been updated with a new key should be disregarded.

key0 -> sign(key0, key1+data1) -> sign(key1, key2+data2) -> ... -> sign(keyN-1, keyN+dataN)

Keys can be repeated e.g. key1=key0 if one only wants to sign for some data. The first key is "authbase" and last key is "authhead". The data can be whatever you want - it can be used for a web of trust where you use an authhead to attest that some other authchain is linked to an identity.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

This might be of interest: https://github.com/bitjson/chip-bcmr

It requires a blockchain for timestamping so order of events cannot be forged, but is basically an off-chain convention for identity management.

An "authchain" is a chain of signatures where each key signs for the next key in the chain (or sign for the same key again) + some metadata. Only the latest key is considered the identity's key, and signatures (using old keys) published after authhead has been updated with a new key should be disregarded.

key0 -> sign(key0, key1+data1) -> sign(key1, key2+data2) -> ... -> sign(keyN-1, keyN+dataN)

Keys can be repeated e.g. key1=key0 if one only wants to sign for some data. The first key is "authbase" and last key is "authhead". The data can be whatever you want - it can be used for a web of trust where you use an authhead to attest that some other authchain is linked to an identity.

Correct me if I'm misunderstanding, but wouldn't this just mean that if an attacker got hold of your private key, all they'd need to do is sign for another key and they'd have full control of your identity? The way it works right now, if an attacker got hold of your private key, at least they couldn't shut you out of publishing under that identity.

from nostr.

A60AB5450353F40E avatar A60AB5450353F40E commented on August 20, 2024

I very much liked this argument:

For lost keys there are some ideas of making a best-effort transition to a new pubkey by notifying followers, but this is a somewhat impossible problem no matter how you tackle it. Somehow, somewhere, some keys must be kept safe. If you lose everything you lost everything. Right?

With that in mind

Correct me if I'm misunderstanding, but wouldn't this just mean that if an attacker got hold of your private key, all they'd need to do is sign for another key and they'd have full control of your identity?

Yes, you understood right.

I'm going to have to go a little off-topic here, going to quote what the author (Jason Dreyzehner) of BCMR had said when publicly discussing the proposal:

If you get hacked and the attacker steals your identity, you have to "revoke" it socially – announce on your website, talk to contacts, get various trusted registries to update to your new authbase, etc. It's much, much easier to keep your identity secure (like with funds), but identities necessarily have a social context, so they're actually more "recoverable" than stolen BCH/tokens.

Another notable use case would be for Tor websites to have persistent identities over time. A lot of hidden services use PGP keys, but if the service gets hacked, you can no longer tell the difference between the owner and the hacker. If you use proper on-chain BCH identities, you can leave control of the identity in multisig or cold storage, and only sign with a "warmer" key. If you get hacked, just broadcast the next update to the identity to revoke the old key (and even broadcast a new .onion address)

An important feature of this system is that historical keys don't matter: if a key holder leaves your company and you rotate them out of the multisig (spend the identity output forward to a new multisig contract), their old key is useless. You could even (as a policy) publish all former keys to ensure old identity outputs are never used for social engineering ("here's an off-chain message that was signed by X's identity!").

Note that we are not using "addresses", only outputs. Every output can be spent only once, and the chain mediates disputes. Bitcoin (Cash) has the verifiable revocation system that PGP always lacked 😄

So, it doesn't have to be 1 user 1 authchain. You could have a cold-storage authchain used to prove that some other authchain is yours. If you lose access to all of it, you'd have to reach out to your social circle, and have them use their authchains to attest that they have talked to you and confirmed that your identity was stolen.

The way it works right now, if an attacker got hold of your private key, at least they couldn't shut you out of publishing under that identity.

But it also prevents you from moving to a more highly-secured key, and maybe one day to a quantum-secure key if your identity auth chain will have lasted that long.

from nostr.

A60AB5450353F40E avatar A60AB5450353F40E commented on August 20, 2024

Would it be possible to make nostr protocol to support multiple identity protocols? Imagine some interface for an identity module, and using nostr as the default module, but make it possible to add others? You could then have namespaces like nostr:username, bcmr:username, keybase:username, ion:username.

Edit: skimming this DID spec, @alvistar is this "DID" specification trying to achieve this? So, nostr/bcmr/keybase would be different methods in the did:method:id scheme?

Your base proposal relies on keys, however consider the BCMR blockchain protocol which relies on spending TX output0 (whatever its locking script is) - this means you can temporarily delegate posting to a contract and revoke it after some time or other condition. I don't know if you favor a particular blockhain or not, but consider that BCH has covenants (through TX introspection opcodes), so you can, for example, enforce that 1 key from the multisig carries over so you can allow some other key to spend from it to make posts on nostr but it will be unable to "steal" the identity since the other, master, key will always be part of multisig.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Hi, everybody, I just read about Nostr protocol from Twitter messages and went reading immediately the specs.

I immediately saw issues in just using pub key as identities because this is static, as already posted above.

I do suggest to have a look at decentralized identifiers did - https://www.w3.org/TR/did-core/

To look at some promising implementation look for ION - https://github.com/decentralized-identity/ion

And guess what, that”s the same used by https://developer.tbd.website/projects/web5/

anyway, the idea would be including the did in the event instead of the pub key. Then relay should resolve the did, check which is the current valid pub key for signing and verify the signature.

I was short in writing, but I’ll be glad to reply I’d something is not clear.

I'm familiar with DID and was initially excited about ION, but the more I thought about it, I'm not sure I want a single identity connected to everything across the Internet. There's a real threat of getting added to a blocklist that governments or corporations force network participants to abide by (think OFAC sanctions). If you have a problem in one corner of the Internet, now your identity is at risk everywhere.

That aside, I can't find anything in ION that details how key rotation would work. Is there something specific you could point to regarding DID key rotation?

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Thinking more about it, I don't think we need the first NIP mentioned above, where users vouch for each other. Vouching for various trust areas of a key should be handled by a reputation scheme like nostr-protocol/nips#46. Valuable, but not necessary for the purpose being discussed here.

Instead, we just need users to sign the revocation NIP's event itself, essentially endorsing the claim being made. Yes, this old pubkey is replaced by this new pubkey. That's a far more narrow responsibility without any crosscutting concerns, like also endorsing the pubkey's current username.

Given that discussions surrounding possible NIPs seems to have moved to the nips repo, I'll start a discussion over there.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

Hi, everybody, I just read about Nostr protocol from Twitter messages and went reading immediately the specs.
I immediately saw issues in just using pub key as identities because this is static, as already posted above.
I do suggest to have a look at decentralized identifiers did - https://www.w3.org/TR/did-core/
To look at some promising implementation look for ION - https://github.com/decentralized-identity/ion
And guess what, that”s the same used by https://developer.tbd.website/projects/web5/
anyway, the idea would be including the did in the event instead of the pub key. Then relay should resolve the did, check which is the current valid pub key for signing and verify the signature.
I was short in writing, but I’ll be glad to reply I’d something is not clear.

I'm familiar with DID and was initially excited about ION, but the more I thought about it, I'm not sure I want a single identity connected to everything across the Internet. There's a real threat of getting added to a blocklist that governments or corporations force network participants to abide by (think OFAC sanctions). If you have a problem in one corner of the Internet, now your identity is at risk everywhere.

That aside, I can't find anything in ION that details how key rotation would work. Is there something specific you could point to regarding DID key rotation?

Hi,
regarding first problem , I think it's a no problem.
In the current things of NOSTR the same will apply using the pub key, they can blocklist all messages coming from that pubkey.
Yes, of course, you can change pub key but then it's like your change your identity. How can you prove you are the same person signing with old pub key? If you manage to prove it to the public, also adversaries will know it an block the new key.

In DID world you can always create a new identifier, this will solve this issue, but it's like your change your identity.
There are no personal data attached to DID, it's just some bytes that are meant to be unique inside a DID method.

And by the way, there are DID schemas that are already made of static private keys.
See https://w3c-ccg.github.io/did-method-key/

Regarding Sidetree ION, key rotation is in the specs. Have a look at
https://identity.foundation/sidetree/spec/#update

You can update all the DID document, including keys.

Summary, using a DID instead of plain pub key:

  • you have the same advantages of what you are doing today - you can just use did-method-key
  • you will be able to support all the advancements in DID
  • you need to simply be able to resolve the DIDs, from an identifier, resolve the pub key and then validate the signature

Happy to get back if needed.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Can someone please point to a simple example implementation of a DID?

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

I have a DIDWeb resolver in Kotlin here: https://github.com/WorldHealthOrganization/ddcc-validator/blob/main/trust-didweb/src/main/java/org/who/ddccverifier/trust/didweb/DIDWebResolver.kt and in JavaScript here: https://github.com/Path-Check/did-web-resolver/blob/main/lib/DIDWebResolver.js

DID:WEB is basically a json in the well-known directory of a HTTP address, looking like this (3 keys in it):

{
  "id": "did:web:example.com",
  "verificationMethod": [
    {
      "id": "did:web:example.com#key-0",
      "type": "JsonWebKey2020",
      "controller": "did:web:example.com",
      "publicKeyJwk": {
        "kty": "OKP",
        "crv": "Ed25519",
        "x": "0-e2i2_Ua1S5HbTYnVB0lj2Z2ytXu2-tYmDFf8f5NjU"
      }
    },
    {
      "id": "did:web:example.com#key-1",
      "type": "JsonWebKey2020",
      "controller": "did:web:example.com",
      "publicKeyJwk": {
        "kty": "OKP",
        "crv": "X25519",
        "x": "9GXjPGGvmRq9F6Ng5dQQ_s31mfhxrcNZxRGONrmH30k"
      }
    },
    {
      "id": "did:web:example.com#key-2",
      "type": "JsonWebKey2020",
      "controller": "did:web:example.com",
      "publicKeyJwk": {
        "kty": "EC",
        "crv": "P-256",
        "x": "38M1FDts7Oea7urmseiugGW7tWc3mLpJh6rKe7xINZ8",
        "y": "nDQW6XZ7b_u2Sy9slofYLlG03sOEoug3I0aAPQ0exs4"
      }
    },
  ],
  "authentication": [
    "did:web:example.com#key-0",
    "did:web:example.com#key-2"
  ],
  "assertionMethod": [
    "did:web:example.com#key-0",
    "did:web:example.com#key-2"
  ],
  "keyAgreement": [
    "did:web:example.com#key-1", 
    "did:web:example.com#key-2"
  ]
}

Nostr's public key field then would be: "did:web:example.com#key-2", which would resolve to https://example.com/.well-known/did.json and take key-2 in the file.

Users can then delete the key from the json when it leaks.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

And here's an implementation of the aforementioned DID:KEY method in rust: https://github.com/decentralized-identity/did-key.rs

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

Here's a question. Let's say Nostr uses DIDs instead of public keys, a person's key leaks and they remove it from the DID Document. Shall relays delete all past events that were signed with that key since they are not verifiable anymore?

One can argue we lose the history of that person, but the attacker can insert past events into a relay. So, nothing is reliable anymore.

Maybe this is a good way to implement the right to be forgotten.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

What kind of load this would this add to the relays/clients to have to resolve every single message?

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

It depends on the method. DID:KEY doesn't need to download anything. DID:WEB does require a download, but people generally implement a local cache for them (refreshing once in a while, similar to NIP05). Other DID methods like DID:IPID for IPFS resolvers or DID:ION, rely on local nodes. Caching is resolved at the node level.

That's why I advocate for a NIP to specify which DID Methods should be implemented by relays and clients.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

Here's a question. Let's say Nostr uses DIDs instead of public keys, a person's key leaks and they remove it from the DID Document. Shall relays delete all past events that were signed with that key since they are not verifiable anymore?

One can argue we lose the history of that person, but the attacker can insert past events into a relay. So, nothing is reliable anymore.

Maybe this is a good way to implement the right to be forgotten.

Interesting point.
I see 3 way out of it

  1. RIght of be forgotten as you mention
  2. Trust on the relay timestamps
  3. Commitment to a blockchain, like ION is doing. Basically using a blockchain as clock to prove somebody existed at time X

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

I would hope we choose to never have to trust relays.

On 3, the event date is unreliable (the attacker can post in the past). So, you would have to rely on the date of receipt of the event by the relay or by the client. And use that date to ping ION. Resharing an unverifiable event would fail unless you trust the date of the receipt by the relay/client, which feels shaky.

1 is the easiest option.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

3 is complex.
But it would work in different way. A relay would need to hash all different messages received, compute something like a merkle tree, and inserting the resulting hash in a something like a bitcoin transaction.
Then you can't forge any message "in the past" with compromised keys as even if the signature is valid, there is no proof in the blockchain.
That's more or less the way sidetree (ion) is working.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Before even trying to solve those problems, my initial concern is this: do we really want to outsource such a core part of the network to external service providers? What happens when those DID methods are no longer supported? Yes, DID could solve key rotation, but it introduces a lot of additional risks since it outsources such a core responsibility of the network.

Right now identity on nostr is handled using long-standing public protocols and validation is local and very fast. Relays and clients do not depend on external services for this.

Bringing it back to the major problem we're trying to solve here: how do we allow network participants to recover from a compromised private key? To that end, what's the downside to @fiatjaf's proposal here? nostr-protocol/nips#103

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

I would say the nostr-protocol/nips#103 proposal is more complicated than a DID implementation and it still runs into the problem of impersonation by stealing the seed and creating new keys to invalidate the user's own current keys. User and attacker will keep creating new keys one on top of the other.

And even after the user has taken a new key, the attacker can still broadcast valid previous-key payloads in the past. This leads to the same question: do relays delete old payloads because those keys are not reliable anymore or do they keep them around and the protocol has to deal with the inconsistency of resharing previously-valid-but-now-invalid-payloads.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

Before even trying to solve those problems, my initial concern is this: do we really want to outsource such a core part of the network to external service providers? What happens when those DID methods are no longer supported? Yes, DID could solve key rotation, but it introduces a lot of additional risks since it outsources such a core responsibility of the network.

Right now identity on nostr is handled using long-standing public protocols and validation is local and very fast. Relays and clients do not depend on external services for this.

As @vitorpamplona pointed out you are not outsource to network. DID:KEY is basically what exists now, it doesn't depend on the network at all, you can verify without external network calls.

If you want to introduce your own schema, you can do that, call it DID:NOSTR, and having the schema you suggest. But you are leaving open to use other mechanism, provided if client and relays agree.

You can eventually specify in NOSTR protocol specification which DID methods to use at least. This would be the same as saying you need to support this auth schemas.

I see here more flexibility, path for rotation of keys, without adding too much complexity. And not depending necessarily on external services.

Bringing it back to the major problem we're trying to solve here: how do we allow network participants to recover from a compromised private key? To that end, what's the downside to @fiatjaf's proposal here? nostr-protocol/nips#103

I am not entering that proposal specifically, but even using a seed with KDF just shift the problem to what if the seed is compromised...

from nostr.

alvistar avatar alvistar commented on August 20, 2024

I would say the nostr-protocol/nips#103 proposal is more complicated than a DID implementation and it still runs into the problem of impersonation by stealing the seed and creating new keys to invalidate the user's own current keys. User and attacker will keep creating new keys one on top of the other.

And even after the user has taken a new key, the attacker can still broadcast valid previous-key payloads in the past. This leads to the same question: do relays delete old payloads because those keys are not reliable anymore or do they keep them around and the protocol has to deal with the inconsistency of resharing previously-valid-but-now-invalid-payloads.

I tend to agre, that's why I would think to keep NOSTR simple. Support something like DID:KEY are you using today, and outsource this very complex problem of decentralized identifiers.

I would focus on what to do on the messages if the keys get compromised as suggested.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

I am not entering that proposal specifically, but even using a seed with KDF just shift the problem to what if the seed is compromised...

The idea is to have a seed that can stay completely offline while one of the derived keys can be used in a hot environment for frequent signing.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

Yes, I have got it. For that can I simply suggest to use BIP32. You have a hierarchical tree of keys and there already hardware secure storage like Ledger supporting it.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

How does nostr-protocol/nips#103 integrate with the secure chips in people's phones?

Assuming that would be a large section of the user base, the protocol should facilitate the use of those chips. From what I understand, that proposal requires the use of fixed private keys created elsewhere and manually inputted into apps as opposed to creating keys inside the chip and simply adding their public keys to a list of keys the holder controls in a DID Document.

I think the UX should be considered here.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Yes, I have got it. For that can I simply suggest to use BIP32. You have a hierarchical tree of keys and there already hardware secure storage like Ledger supporting it.

Correct me if I'm wrong, but I don't believe that'll work for us. nostr-protocol/nips#105 (comment)

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

How does nostr-protocol/nips#103 integrate with the secure chips in people's phones?

Assuming that would be a large section of the user base, the protocol should facilitate the use of those chips. From what I understand, that proposal requires the use of fixed private keys created elsewhere and manually inputted into apps as opposed to creating keys inside the chip and simply adding their public keys to a list of keys the holder controls in a DID Document.

I think the UX should be considered here.

NIP-26

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

How does nostr-protocol/nips#103 integrate with the secure chips in people's phones?
Assuming that would be a large section of the user base, the protocol should facilitate the use of those chips. From what I understand, that proposal requires the use of fixed private keys created elsewhere and manually inputted into apps as opposed to creating keys inside the chip and simply adding their public keys to a list of keys the holder controls in a DID Document.
I think the UX should be considered here.

NIP-26

It's a different use case: nostr-protocol/nips#103 (comment)

would we have then a seed + a set of keys from phones? this is getting complicated.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

It's a different use case: nostr-protocol/nips#103 (comment)

I'm not sure I agree with @fiatjaf there. From the NIP itself:

For example, a user could generate new keypairs for each client they wish to use and authorize those keypairs to generate events on behalf of their root pubkey, where the root keypair is stored in cold storage.

would we have then a seed + a set of keys from phones? this is getting complicated.

Either with NIP-26 or DID, a user would have to copy the public key from the phone and save or publish it somewhere signed by their root key to effectively declare that this pubkey is them. In this regard, I'm not sure how it's any more or less complicated either way.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

Either with NIP-26 or DID, a user would have to copy the public key from the phone and save or publish it somewhere signed by their root key to effectively declare that this pubkey is them. In this regard, I'm not sure how it's any more or less complicated either way.

Correct, but the DID makes both the SEED-key-expiring scheme and NIP-26 obsolete. Why do two complicated things if you can solve both with one?

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

SEED-key-expiring scheme

?

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

SEED-key-expiring scheme

?

nostr-protocol/nips#103

from nostr.

alvistar avatar alvistar commented on August 20, 2024

Yes, I have got it. For that can I simply suggest to use BIP32. You have a hierarchical tree of keys and there already hardware secure storage like Ledger supporting it.

Correct me if I'm wrong, but I don't believe that'll work for us. nostr-protocol/nips#105 (comment)

Read it, but not sure what it does mean.

The overall idea here would be keep a parent key(1) safe in hardware, put the child private key(1/1) in client. Make the pub key(1) used as identity. Use private keys (1/1/x) for signing.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

That's funny, on the other thread I was just about to suggest that you take a stab at something like this. I'm not familiar enough with DID specs to understand everything that's going on here yet. But at a high level, this feels like the right way of going about it. Just make it an event type and everything remains self-contained to the network. 👍

I'll dig into this to better understand it.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

The only issue is the consensus in allowing DIDs in the "pubkey" attribute. I would migrate all non dids to a did:bip340: as previously described and allow a new did:nostr in the field.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

It would be an evolution of NIP-26, allowing multiple keys and behavior types.

Would be interested to hear @markharding's thoughts on that.

The only issue is the consensus in allowing DIDs in the "pubkey" attribute. I would migrate all non dids to a did:bip340: as previously described and allow a new did:nostr in the field.

Backwards compatibility is highly prized around here, so might just have to stick with the recommendation that the lack of a did prefix means the current method prevails.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

I'd suggest this new event with a DID document should be a replaceable event and be timestamped.

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

Backwards compatibility is highly prized around here, so might just have to stick with the recommendation that the lack of a did prefix means the current method prevails.

Apologies, that's what I meant.

I'd suggest this new event with a DID document should be a replaceable event and be timestamped.

Good enough. No history of DID Docs but maybe there is no need for a historic recollection in nostr.

from nostr.

alvistar avatar alvistar commented on August 20, 2024

@csuwildcat Hey, I have been silent, but I am following you and your work since long time.
It's an honour to see you here.
As you see, I am spreading the word of DIDs and ION, no necessity to reinvent the wheel every time.

How is going at Block? Between one popcorn and another, it would be interesting to hear your point of view of nostr... btw I jumped in the discussion after I see Dorsey tweets...

from nostr.

vitorpamplona avatar vitorpamplona commented on August 20, 2024

Correct me if I am wrong, but the pubkey rotation means you cannot decrypt regular NIP04 PMs with the old address anymore, right?

In that sense, rotating keys through nostr-protocol/nips#103 solves a key leak issue (discard the past), but it doesn't help the implementation of a regular key rotation policy where the old key is still safe and thus PMs should be visible to the user and valid. It's also not helpful when using different private keys per device. PMs will not be able to be read by different devices even though they are safely controlled by the same user.

from nostr.

fiatjaf avatar fiatjaf commented on August 20, 2024

Good point.

from nostr.

kevinsmith avatar kevinsmith commented on August 20, 2024

Migrated the comment originally posted here to nostr-protocol/nips#116

from nostr.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.