Previously go-ipfs generated 2048 bit RSA keys for new nodes, but it will now use ed25519 keys by default. This will not affect any existing keys, but newly created keys will be ed25519 by default. The main benefit of using ed25519 keys over RSA is that ed25519 keys have an inline public key. This means that someone only needs your PeerId to verify things you’ve signed, such as your Peer Records or in the future Signed Provider Records, which means we don’t have to worry about storing bulky RSA public keys.
Note the part i made bold.
How do i do that?
I can’t seem to find any command in the IPFS cli to do exactly what is described there. I’m sure there’s something (right?)
I’m working on a little tool for server-to-server communication.
Now there are a load of different ways to verify that “Server X” added a file. The file contains some instructions for another server to handle. This is broadcasted via a “pubsub like” mechanism (i’m not using IPFS for this part).
I want to verify that the messages that “Server X” sends are actually from that server (it’s peerid is known) so that any of the other servers can pick the message up, verify it to be a valid message and handle it.
If i’m following the logic to verify an ed25519 key i’d need to do:
the signature (is the result of ipfs add <data> the signature, so the hash?)
the public key (the peer id)
verify the signature with the public key
Is that how it’s supposed to work? I have to admit that i haven’t actually tried this yet…
@johndeoi@markg85 is correct. This change does not impact that behavior at all. If you’re running a libp2p node (like go-ipfs) then you can verify who is sending you all traffic since a verified communication channel is established between peers.
There’s certainly no functionality to determine who asked for mygateway.tld/ipfs/Qmxyz aside from putting a proxy in front and checking things like source IP addresses. Requesting data over the gateway just uses HTTP so there isn’t a good way to force the user to identify itself (although you could of course build your own via a proxy).
Hashes are not signatures. I’d recommend taking a look at the IPFS docs (or https://proto.school) for more background. In short hashes verify that the content is what you expect (H = Hash(Data)), while signatures verify that a particular key holder has signed that data (S = Sign(Data, Key)). The places signatures are used in applications such as go/js-ipfs are for some lower level libp2p functionality such as secure connection protocols like TLS and Noise, as well as for signing IPNS records.
I’m not sure how the peerID is known, but since it doesn’t seem like this application is using libp2p or any low level functionality in IPFS you may be able to get away with using a signing key that is separate from your peerID. Nonetheless, if you are trying to sign arbitrary data with your peer’s ID key you want to be looking at using IPFS as a library since go/js-ipfs do not expose a PGP like interface (e.g. ipfs key sign --key=mykey mymessage) mostly because there are already tools out there (e.g. PGP) that will handle key signatures/verification for you.
Would a VM proxy help me isolate specifc data in regards to file systems/networking? and change/ view my own perhaps in a more functional way? as opposed to only accessing/having direct accress via a single device? What i am curious about is lan internetworking for the purpose of better understanding protocols and syntax of the stack structures being used.
I should’ve know that the hash isn’t a signature, my bad.
I see what you mean. IPFS provides the public key (peer id) and the data but not the actual signature! That does make me wonder what the release notes meant with “This means that someone only needs your PeerId to verify things you’ve signed”? As that doesn’t seem to be possible based on your comment. At least not from a IPFS cli point of view. I have a feeling i miss something here as i can’t imagine the release notes to mention something that isn’t possible.
Going the PGP route, as you suggest, is an alternative option indeed.
The annoying part is that it adds a layer.
To give you an example, i really would have liked to do:
// Store some data in IPFS, get the CID of it
echo "some fancy data" | ipfs add
// Get the IPFS Peer ID as ed25519
// Send to pubsub
pubsub-send --pubkey=<IPFS peer ID> --data=<cid>
// On one of the servers i would like to do something like
// (note that it would fetch the data behind <cid>):
ipfs key verify --pubkey=<IPFS peer ID> --data=<cid>
Right now the only missing part is getting the signature of that data.
If IPFS would only have a:
That would be so super awesome to have!
It would prevent the need to roll my own key management.
It would greatly simplify the usage of keys.
It would only require me to store a list of accepted public keys.
It would allow me to verify the data is valid (due to the immutable nature of IPFS) without downloading the data. And on;y download it when all other checks have passed
Easy peasy and super awesome!
… but we’re not there yet, it seems
For a time I may suggest you create the dedicated DAG branch containing the hash text calculated from the given CID and the peer ID, linked as another CID insige DAG object using ipfs object patch add-link. Investigating the possibilities I try to use pymultihash to produce something like digital signature.
Sorry for the belated reply, @zicmama.
Yes, that can very definitely help! Thank you for sharing those tools.
I am however hesitant to use it because it means i’d have to do key management myself.
I’m still eagerly awaiting what exactly was meant with that line in the release notes:
… This means that someone only needs your PeerId to verify things you’ve signed …
As that kinda triggered my hope for key management in ipfs native. We, as users, can somehow verify that Node X actually created Data Y. Or to be super specific. That IPNS record X is created by node Y.
I just don’t see it without additional steps (like making a signature). And if that’s actually the case here then that specific line in the release notes is misleading at best. Also, that very same line definitely implies (with “things you’ve signed”) that IPFS now has the user facing option to do just that. And i read that from it because doing that yourself is not trivial. Why, you might wonder?
data signing is, even for technical inclined people like ipfs users, a whole different beast to tame. You can safely expect for the vast majority of IPFS users that this is a step too complicated.
The release notes mention that you can verify data with the peer id. But it lacks any public facing ways of signing data. Therefore you must do it yourself. And to do it yourself you must:
2.1 Get your private key from IPFS
2.2 Construct a keypair from it
2.3 Create a signature from your data
2.4 Store it somewhere
2.5 Send it to the one that needs to verify your data based on your peer id
2.6 … the receiving party needs to go though much of the same steps
I honestly just can’t imagine that IPFS would assume that users are able to all of the above. But i also can’t imagine it to be completely false. Surely the writer of those release notes had “something” in mind and knew “something” but didn’t share the intention here yet.
IPFS (or rather libp2p) will do it out of the box. It’s not implemented yet, but it’s on the short term road map. There will be customizable behaviour as to whether to sign records and what to do with unsigned records. I expect the default to be signing and accept anything, then signing and reject unsigned in a few releases, for a smooth network upgrade. There is a Github issue somewhere, but I think it’s at the spec stage.
It was a lost of man-hours to implement it before switching to ed25519, so they waited until now.
It will be especially useful for gossipsub hardening, as upfs will not only check the record when fetching it, but also when propagating the record, since it doesn’t need to have contacted the publishing node to check its jey and the record integrity.
This + the github issue you mentioned. That’s awesome!
Having that in pubsub is a win imho!
However… It’s still not something a user of ipfs (or even a developer using ipfs) can possible use as it’s a quite deep internal implementation detail in libp2p that handles it.
I do hope it’s the intention at some point to somehow for pubsub have some way of whitelisting (or blacklisting) peer id’s which internally then does signature verification. That allows to create pubsub channels where only selected nodes can understand the data. Of if you go one step further, only selected nodes can join that room. Good stuff
More generic ipfs commands for this would be really useful. Even though there are dedicated security crypto libraries out there, which is always the argument for not doing this. It just saves so much hassle to simply be able to create a signature from the ipfs cli and verify it with a cli command too.
you get a libp2p format binary blob.
As per the documentation:
ipfs key export test
ipfs key export <name> - Export a keypair
ipfs key export [--output=<output> | -o] [--] <name>
<name> - name of key to export
-o, --output string - The path where the output should be stored.
Exports a named libp2p key to disk.
By default, the output will be stored at './<key-name>.key', but an alternate
path can be specified with '--output=<path>' or '-o=<path>'.
I was trying to make a command line tool that would only require openssl 3.0.0 in which you would provide your ipfs private key to sign an ipfs hash (no need to sing the content as the hash represents the content) to get that signature. But from the looks of it i need to go the much more complicated route of making a application that accepts protobuf, parse that key output from ipfs key export test and the finally be able to sing…
And i’m sure i still missed something that i have yet to discover.