Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Question: Key type returned by crypto.keys.unmarshalPublicKey #184

Closed
acolytec3 opened this issue Jan 11, 2021 · 4 comments
Closed

Question: Key type returned by crypto.keys.unmarshalPublicKey #184

acolytec3 opened this issue Jan 11, 2021 · 4 comments

Comments

@acolytec3
Copy link

In a web app I've recently built, I am generating RSA keys using the PeerID library and then using those keys to encrypt and decrypt messages sent via libp2p.dialProtocol between two browser-based libp2p nodes. The basic flow for passing the public between the two nodes is as follows:

  • Node 1: create peerID using PeerID.create({keyType:'RSA'}) and then start up a node using that generated peerID
  • Node 1: Present libp2p.peerId.toJSON().pubKey as a QR code
  • Node 2: Read the string of Node 1's public key and convert to PeerID using PeerID.createFromPubKey(node1PublicKey)
  • Node 2: Derive Node 1's public key using libp2p-crypto.keys.unmarshalPublicKey(node1.peerId.marshalPubKey())
  • Node 2: Typecast the derived node1 public key to an RsaPublicKey
  • Node 2: Encrypt messages using node1publickey.encrypt(...message...)
  • Node 1: Derive RsaPrivateKey from node 1's peerId using crypto.keys.unmarshalPrivateKey
  • Node 2: Decrypt messages using the derived RsaPrivateKey

This all works as outlined here. I can link to the specific code as needed but it's still in pretty rough form in my repo.

The issue I'm finding is that Typescript tells me that crypto.keys.unmarshalPublicKey returns a key of Crypto.PublicKey which doesn't expose the encrypt and decrypt methods. I can use //@ts-ignore and everything works as I outlined above but if I use crypto.keys.supportedKeys.rsa.unmarshalRsaPublicKey to satisfy Typescript where I use crypto.keys.unmarshalPublicKey above, I get this error Error: Cannot read public key. ASN.1 object does not contain an RSAPublicKey. and the app crashes, even though peerID I'm generating the public key from has the RsaPublicKey property when I inspect it in the browser console.

I'm not sure if there's a better way to get at what I need or if I'm doing something wrong but why would crypto.keys.unmarshalPublicKey successfully derive a key and not the crypto.keys.supportedKeys.rsa.unmarshallRsaPublicKey method? Alternatively, is there a possible improvement to crypto.keys.unmarshalPublicKey/PrivateKey where we could specify the key type as a parameter in the method so that it would return whichever of the supported key types (RSA/ed25519/secp256k1) so library users could make use of the full set of methods supported by each specific key type?

@vasco-santos
Copy link
Member

Hey @acolytec3

Thanks for reporting this. Two things that we will need to consider here:

  • libp2p crypto types still need to be properly created using JSDoc, which is not the case. This might be causing ts problems at the moment. We have an issue tracker for this work in Support for Typescript users js-libp2p#659 . There is still a long way to go, we started for the core APIs as they are the most used by libp2p users
  • we want to work later this year in a crypto overhaul to improve both the libp2p-crypto API and make it configurable to allow us to bundle only what users need and decrease the build bundle size. The issue is Overhaul libp2p-crypto js-libp2p#586

You are doing what is expected according to the current API. I recommend that you keep with the ts-ignore for the time being and track the ts issue above for updates on this.

If you have any suggestions or feedback, feel free to let us know as we did not spend a big time thinking about this yet. If you would like to help out with the types for libp2p-crypto using JSDoc that would be great and would help with this.

@acolytec3
Copy link
Author

@vasco-santos Understood, thanks for validating my understanding. I started digging into it a bit, fixed a couple of simple things that would prevent JSDoc from working. That said, libp2p-crypto is a big chunk of work given the large number of exports I'd have to dig through. I'm game to try and take it on but don't want to bite off something too big. Would sufficient initial PR be to map the current type definition to JSDoc annotations?

@vasco-santos
Copy link
Member

Understood, thanks for validating my understanding.

Happy to help

Would sufficient initial PR be to map the current type definition to JSDoc annotations?

Yes, that would be better, small iterations to ease development and review. This needs aegir to be updated to its latest version and based on this docs and some example PRs like libp2p/js-libp2p#802 . So, this will generate type definitions on release, but you can look at them by running the build script with aegir.

@acolytec3
Copy link
Author

Okay, I'll poke around with it. I have started experimenting with upgrading aegir and generating the type definitions but it's going to be a little harder than just updating the existing type definition since I'm not familiar with aegir and all that. If/when I can get something that looks roughly right based on the PRs you linked to, I'll submit a new one. Will close this issue for now as my question is answered.

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

No branches or pull requests

2 participants