Exporting crypto keys for work with GPG

I wish to use a libp2p node’s public key to encrypt some data, which I would the store to ipfs and know that only that node can decrypt it (using its private key).

pubkey, _ := peerID.ExtractPublicKey()
pubkeyBytes, _ := crypto.MarshalPublicKey(pubkey)
f, _ := os.Create("pubkey")
f.Write(pubkeyBytes)

So far so good; but here comes the problem:

MarshalPublicKey converts a public key object into a protobuf serialized public key

Sow do I export the public key into a standardized format understandable (for example) by GPG?

I don’t currently know of any libraries that will take a libp2p Key and turn it into a GPG key, although nothing stops you from doing that.

The Key interface has a Raw function for getting the raw key bytes out, and the Type function for figuring out what type of key it is (you could also do a type cast on the interface, but this is better if there are multiple implementations of the same key type). These two should be sufficient to be able to export the key.

If you end up writing some code doing the GPG import/export post back so other people can find it :slight_smile:.


Note: peerID.ExtractPublicKey() is only going to work on small keys (e.g. Ed25519), however, if the key is large (e.g. RSA keys) then the peerID becomes the SHA256 hash of the protobuf containing the key and you therefore can’t do an extraction.

An implementation of the KeyBook interface, such as the one in the Host’s Peerstore, might know about a peer’s corresponding public key (e.g. host.Peerstore().PubKey(peerID)) if you’ve connected to them.

Also, IIRC GPG compatibility with certain key types (like Ed25519) is a bit annoying (i.e. not everything supports it). So you’ll have to tackle that when you do your import.

Thanks for the info! :slight_smile:

The Key interface has a Raw function for getting the raw key bytes out

So the raw key bytes are already the same that, for example, GPG would genererate - no further weird transformations of data are necessary?

Also, IIRC GPG compatibility with certain key types (like Ed25519) is a bit annoying (i.e. not everything supports it). So you’ll have to tackle that when you do your import.

Could you explain this a bit further please? I intended to just export the key and then use golang’s cmd execution to execute appropriate bash commands. What compatibility issues could I run into here?

No promises there, just that any weird transformations that you’d have to make are not libp2p specific (e.g. the protobuf wrapping). For example it looks like the Raw RSA public key bytes come from x509.MarshalPKIXPublicKey code, so if the GPG library you’re using wants the data in a different format then you’ll need to figure that out.

Mostly that from my brief Googling adventure I’ve noticed that Ed25519 is not part of the OpenPGP specification and generally some ambiguity around where it’s implemented + supported.

Generally my answer was on how to get your keys out of libp2p into a more generic format. However, if you’re working with cryptographic keys you should make sure that you’re doing things that are safe + supported by the underlying primitives.

For example, don’t use the same keys for signing and encryption, try to minimize the number of different ways your signing key is used (e.g. to prevent someone tricking you into signing something in one context that means something else in a different context), etc.

Thanks, I’ll look into it.