ipfs / specs

Technical specifications for the IPFS protocol stack
https://specs.ipfs.tech
1.15k stars 232 forks source link

IPNS Key Revocation #219

Open aschmahmann opened 4 years ago

aschmahmann commented 4 years ago

There is currently no scheme in place for revoking IPNS Keys. Revocation is important since IPNS security relies on the security of an underlying asymmetric key. However, what happens when those keys are deemed no longer secure (e.g. RSA-1024 no longer deemed secure, discovered bug in RNG used to generate keys, laptop stolen...).

One scheme that's pretty easy to implement is reserving the sequence number MaxUInt64 as indicating that an IPNS record has been revoked. It's basically implied anyway because you cannot publish updates after sequence number MaxUInt64, however this would embed in the spec that we should return an error and not the data if the record has been revoked. There are also other potential options we could explore if we're interested.

@lidel @hugomrdias @Stebalien Thoughts?

Stebalien commented 4 years ago

A max record sounds reasonable. We could even include data as some form of less secure error message (keys are often revoked even when they're not totally broken).

Note: IPNS needs to be reworked anyways. The way we do signatures is technically not broken due to dumb luck. See https://github.com/ipfs/notes/issues/249.

lidel commented 4 years ago

Something I'd like to see in revocation spec is ability to point at a new key, to enable seamless and automated rotation of keys.

To keep things simple, revocation record would point at a new key. Thanks to libp2p-key multicodec we can use regular CID for this, and no additional metadata is needed.

aschmahmann commented 4 years ago

@lidel I'd be nervous about any sort of data being in a revocation record. Here's a scenario that should illustrate why no data is a more robust approach:

  1. Alice has key A1 that is the current IPNS key
  2. Alice creates A2 that is a new IPNS key A2
  3. Alice revokes A1 by setting the record to something like {expired: true, next: A2}
  4. A1 becomes compromised in some way (private key leaked, key too short, etc.) by Bob
  5. Bob creates B as a new IPNS key
  6. Bob publishes {expired: true, next B}
  7. Charlie comes along to resolve A1 and might end up with either A2 or B

This sequence of events basically makes key rotation infeasible. There are some alternatives, but they tend to either require significant changes to IPNS or are brittle. Some examples include:

  1. Make IPNS multi-writer, then Charlie will see both A2 and B and can try and figure out what to do
  2. Change the currentRecord = best(oldRecord, newRecord) function used by IPNS to store {expired: true, next: A2} until it sees {expired: true, next: B} and if so return both options indicating to Charlie that neither are to be trusted (this is a simpler version of multi-writer where multi=2 and as a result we can't see all the options, but might be protected in the simple/safe case)

I wouldn't necessarily feel bad about adding a "hint" to be followed by people so they could make their own decisions about what "the next key" should be. However, this also seems like something that could be dealt with at the application layer.

Note about the multiple writers (whether many or two) solutions

Both of the above schemes are potentially susceptible to various network poisoning/DoS attacks where Bob chases out of the network the records {expired: true, next: A2} until he's confident that his record will stick. This then makes Charlie find his data instead of Alice's.

Unfortunately, this type of attack may already be present in IPNS as a form of rollback-attack (where Bob tries to make Charlie see an old version of the data pointed at by A1). In the case of key compromise a rollback-attack is particularly unfortunate because it means that even a revocation can be rolled back. There is some solace though in that the DoS style attacks require an ongoing attack effort and that once the network heals the correct information will be available again.

daviddias commented 4 years ago

Previous notes on Key Rotation https://github.com/ipfs/specs/issues/31 and on structuring records https://github.com/ipfs/specs/issues/24

aschmahmann commented 4 years ago

@daviddias Any thoughts here on revocation? The suggestion to set sequence number = MaxUInt64 seems like a pretty easy thing to do. Unfortunately, because IPNS (like most distributed systems) is subject to an eclipse + rollback attack it's still not full proof.

Basically it seems like the only downside of doing this is that people might assume IPNS revocation is as robust as signatures are which isn't true, however in non-eclipsing scenarios it does get the job done.