Skip to content

Add support for PKIX and PKCS#8 keys#711

Open
MarcoPolo wants to merge 1 commit intomasterfrom
marco/pkix
Open

Add support for PKIX and PKCS#8 keys#711
MarcoPolo wants to merge 1 commit intomasterfrom
marco/pkix

Conversation

@MarcoPolo
Copy link
Copy Markdown
Contributor

This lets the PeerID format build on standard encodings of keys rather than respeccing this from scratch.

Also lets implementers use and build on existing libraries.

For ML-DSA keys, this lets us reuse all the standarization work done at the IETF: https://www.rfc-editor.org/rfc/rfc9881.html.

This is an alternative to #710.

lidel added a commit to multiformats/multicodec that referenced this pull request Apr 14, 2026
Introduce container codecs for IETF-standard asymmetric key formats that carry the algorithm identifier alongside the key material, so implementers can reuse existing crypto libraries and specs rather than mint a per-algorithm codec for every new scheme.

- pkix-pub (0x40): SubjectPublicKeyInfo (SPKI) per IETF RFC 5280 section 4.1.2.7
- pkcs8-priv (0x41): OneAsymmetricKey (PKCS #8) per IETF RFC 5958 section 2
- both formats self-identify the key algorithm via the embedded AlgorithmIdentifier OID
- codes placed in the single-byte varint range (< 0x80) so existing users of libp2p-key (0x72) in peer IDs and IPNS names can migrate without paying an extra prefix byte per identifier
- 0x40 and 0x41 sit in the unclustered 0x39-0x4f free block, avoiding the ipld/CID-codec neighborhood at 0x70-0x7f

Refs:
- https://www.rfc-editor.org/rfc/rfc5280
- https://www.rfc-editor.org/rfc/rfc5958
- libp2p/specs#711
Comment thread peer-ids/peer-ids.md Outdated
@dennis-tra
Copy link
Copy Markdown

dennis-tra commented Apr 15, 2026

I just read the discussions in #710, #712 and here. I'm posting in this issue here because adding PKIX and PKCS8 doesn't sit with me quite right. At the same time my knowledge is limited so please correct me if my understanding is incorrect.

Some observations:

  1. It's minor but for the new key types there's an increase of the level of indirection by deferring algorithm identification into the Data field.
  2. I don't find it very elegant that KeyType despite being an enum doesn't guard for invariants anymore. According to the proposal certain values are only allowed for either the private or public key message type. One option would be to split it in two. This would preserve the wire format but would be a code breaking change. The two new enums would also have significant overlap. So I'm against that but just wanted to lay out my thoughts.
  3. If this proposal moves forward, I would change the SHOULD to MUST in both backward-compatibility statements. If the same key can be encoded under, e.g., both KeyType.RSA and KeyType.PKIX, those two encodings produce different PeerIDs for the same key which I think should definitely be avoided.

I'm also not sure if maximizing flexibility in the PeerID spec should really be a goal. I'm saying this also in light of the discussion around defining all three MLDSA key lengths in #710. My proposal would be to define a single MLDSA key type (using expanded private keys) while speccing that the encoding should follow PKCS8 and PKIX format (similar to the RSA case). I think this would allow us to still leverage IETF's standardization work while keeping the scope minimal.

As mentioned above, I'm only partially understanding what I'm saying here, so I'm happy to be convinced otherwise.

I'm generally very much in favor to more closely follow IETF work.

@MarcoPolo
Copy link
Copy Markdown
Contributor Author

Hey Dennis, thanks for taking the time to review this.

  1. It's minor but for the new key types there's an increase of the level of indirection by deferring algorithm identification into the Data field.

It's true there is a one-step increase in indirection. But the benefit is being able to reuse a standardized container for these key types. The PKCS#8 container, for example, has the key algorithm identifier at the front. So there isn't much practical cost in reading this identifier.

  1. I don't find it very elegant that KeyType despite being an enum doesn't guard for invariants anymore. According to the proposal certain values are only allowed for either the private or public key message type. One option would be to split it in two. This would preserve the wire format but would be a code breaking change. The two new enums would also have significant overlap. So I'm against that but just wanted to lay out my thoughts.

I'm not opposed to splitting it in two. The "significant overlap" is 4 definitions, right? I don't expect us to add many more key types here, especially if we can reuse IETF standard container to support more key types.

  1. If this proposal moves forward, I would change the SHOULD to MUST in both backward-compatibility statements. If the same key can be encoded under, e.g., both KeyType.RSA and KeyType.PKIX, those two encodings produce different PeerIDs for the same key which I think should definitely be avoided.

No strong objection. I choose SHOULD in case a specific deployment wanted to simplify by always using PKIX/PKCS#8 encodings.

I'm also not sure if maximizing flexibility in the PeerID spec should really be a goal. I'm saying this also in light of the discussion around defining all three MLDSA key lengths in #710. My proposal would be to define a single MLDSA key type (using expanded private keys) while speccing that the encoding should follow PKCS8 and PKIX format (similar to the RSA case). I think this would allow us to still leverage IETF's standardization work while keeping the scope minimal.

I think that looks similar to this, with the extra assertion that the algorithm identifier in PKIX/PKCS8 matches the ML-DSA one. The benefit here is that we focus on how to bridge the IETF container standard itself into libp2p rather than focusing on how this one key type with the standard container fits in.

If we can make these standard containers work generally, then we can avoid bike shedding on any key specific aspects. Such as: why would you propose preventing the seeded private key format for MLDSA?

I do empathize with the point of opting for a smaller scope increase. I would also be fine with a spec change that just added the MLDSA variant used in RFC9118 and used the PKIX/PKCS#8 encodings. I don't think we should prohibit seed format keys.

@MarcoPolo
Copy link
Copy Markdown
Contributor Author

Another alternative is that we register the multicodec for PKIX, and add a line to this spec that allows for a different PeerID representation. Instead of the libp2p-key multicodec it would be pkix (or maybe pkix-hash) and it would be the hash of the DER encoded SubjectPublicKeyInfo.

We only really need to spec out the public key side of this. IIUC the use case for defining the private key is to allow exporting a private key for use by another implementation, which I think is neither a safe nor common practice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

3 participants