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

Key Rotation #31

Closed
daviddias opened this issue Sep 17, 2015 · 3 comments
Closed

Key Rotation #31

daviddias opened this issue Sep 17, 2015 · 3 comments

Comments

@daviddias
Copy link
Member

After learning how a private key can be cracked through plain text + signature sampling (see: #24 (comment)), I've been searching to understand what are other implications and ways to overcome them, taking inspiration from PKI (SSL, TLS, X509, etc) and also from TUF, Notary and Docker Content of Trust.

Problem Statement: If an attacker is able to crack down a private key, they will be able to: 1) Impersonate us and therefore abuse our credibility in their favor, 2) Capture private communication. We can avoid number 2 by having a crypto channel that ensures Perfect Forward Secrecy, making the number 1 the issue the most pressing one.

In the IPFS context, if an attacker could 1) impersonate us, they would be able to: a) publish content as if it was us, b) add provider records that point to a given peer, which could cause a DOS on that peer if a lot of peers try to contact it at the same time for Records that it doesn't even possess.

To illustrate the several problems and possible candidate solutions, I'll go through 3 different scenarios.

Single key-pair

This scenario is simple to illustrate. If we use the same key-pair for everything and if it gets compromised, then an attacker gets full privileges and there is no way other than accepting defeat and rebooting the whole node. Using the same key for everything increases the possibility for crypto analysis and side channel attacks

Multiple 'chained' key-pair (hopefully the right way to go)

In this scenario, we would create a chain of keys with different privileges, using the MerkleDAG data structure:

  • id-key-pair (aka root-key-pair):
    • also used to generate the peerId
    • if it gets cracked, the peer must be rebooted and with the process, reprovide every block (however this is highly unlikely)
    • used to sign the nounce between peers so that authenticity can be assured when providing a record
    • we must avoid assuming that this authenticity is offered by the transport (for example with TLS), as libp2p will support different transports with different capabilities.
  • record-store-key-pair:
    • signed by id-key-pair
    • created to avoid having to use the id-key-pair signing all the records, so that if it gets compromised, we don't have to reboot the peer
    • if it gets cracked, the attacker will be able to create records, but won't be able to provide them because it will be missing the id-key-pair.
    • if can set a larger validity for the record-store-key-pair (like every month) to make it that is very hard for an attacker to have time to crack it. (and peer-Id can be rotated every 6 months, for e.g, making it really hard for brute forcing)
  • record-key-pair:
    • signed by record-store-key-pair
    • used to sign a single record (ensuring freshness for every record)
    • just like the record, this key has validity and stop beings valid when the record is not valid anymore, so if it gets cracked, it won't be able to be used. Also has the same benefit of record-store-key-pair, if it gets cracked, an attacker can generate records for a short period of time, but it would be able to store them in the network because it won't be able to prove it is the actual node by missing the id-key-pair

Multiple 'non chained' key-pair

Very similar to the above with the exception that the record-store-key-pair would not be signed by the id-key-pair, making it impossible to associate who created the record to who is providing it, enabling attackers that compromise the record-store-key-pair to add records to the network pointing to a peer that they do not control for DOS attacks.

Other notes:

  • File blocks/chunks are not signed, only hashed.
@jbenet
Copy link
Member

jbenet commented Sep 18, 2015

Disclaimer: the comments below are from a quick read, i haven't thought it through in detail. I still need to review how TUF works exactly.

  • Yeah, this (how to do key derivation / chaining) is an important problem to get right.
  • I don't think we will find a one-scheme-fits-all solution, but rather should provide function primitives, like descendsFrom(key, ancestorKey Key) bool (offline) and hasBeenRevoked(key Key) bool (online), and others. In the general case, for arbitrary records on DRS, people will have very different-looking PKIs and we don't necessarily want to force them to adopt a single one method of doing things.
  • But yes, it is worth picking one method for ProviderRecords and for IPNSRecords` so that all nodes can implement just one thing.
  • the above does time-based revocation, which may not be optimal on most DRS implementations.
  • the above would generate tons of keys, one per record, with a multiplicative increase on the amount of data people have to download (and store!) per published data block (now they need to get a record, a key, and the data block). I think this is not a good strategy.
  • the above also makes it impossible for peers to relay records offline-- (that is, peer A broadcasts record Ra, peer B receives it. A goes offline. peer B and C establish a connection. peer B tries to send C record Ra. Ra is invalid for C, as C is not receiving Ra from A). record relaying will be a really good way to get efficient and robust record distribution.
  • one other thing, we actually shouldn't necessarily require that the root key be used for setting up crypto channels. we should probably be using derived keys there too.
  • however, before we create an explosion of derived keys, we need a detailed survey of many more approaches.
  • what we should focus on is the abstractions, DRS should have functions to check the validity of keys that can be improved over time

I agree we need to find the right way to do key {storage, derivation, rotation, etc}. But this is a much larger thing than signing records, because it impacts how keys are stored, what keys are stored online vs offline, agents, and so on.

@jbenet
Copy link
Member

jbenet commented Sep 18, 2015

  • also note that the attack mentioned is on ECDSA, not all signing algorithms. Attacks vary according to the key signing algorithms used, so PKI structures + record validity algorithms will have to vary according to key signing algorithm coices, so DRS needs to be able to (a) offload the final choice to the user (via good interfaces), and (b) ship with sane defaults (e.g. ways to do it with RSA, ECDSA, etc)

@jbenet
Copy link
Member

jbenet commented Sep 18, 2015

In any case, really good to get the discussion started. what we should do is gather a bibliography, and multiple other people who can help design the right support for the various schemes.

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

No branches or pull requests

2 participants