Skip to content

Unspecified importKey behavior for PKCS8-encoded raw private keys #356

@ArnaudBrousseau

Description

@ArnaudBrousseau

Summary

The current spec doesn't specify a behavior for PKC8-encoded raw private key import (when I say "raw private key" I mean "without the optional public key bytes").

Chrome and other browsers seem firmly in the camp of "this should be an error" (see this test) and throw a DataError, while Bun and NodeJS import the key without throwing an error.

Steps to repro

Here's a snippet to reproduce the inconsistent behavior:
In Node/Bun ✅

$ node
Welcome to Node.js v20.8.0.
Type ".help" for more information.
> require("crypto")
> buffer = new Uint8Array([48,129,65,2,1,0,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,4,39,48,37,2,1,1,4,32,118,50,222,115,56,87,123,193,44,23,49,250,41,240,128,25,32,106,243,129,247,74,246,15,77,94,3,149,33,143,32,92])
> await crypto.subtle.importKey("pkcs8", buffer, { name: "ECDSA", namedCurve: "P-256" }, true, ["sign"])
CryptoKey {
  type: 'private',
  extractable: true,
  algorithm: { name: 'ECDSA', namedCurve: 'P-256' },
  usages: [ 'sign' ]
}

In browsers 🚫

> buffer = new Uint8Array([48,129,65,2,1,0,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,4,39,48,37,2,1,1,4,32,118,50,222,115,56,87,123,193,44,23,49,250,41,240,128,25,32,106,243,129,247,74,246,15,77,94,3,149,33,143,32,92])
> await crypto.subtle.importKey("pkcs8", buffer, { name: "ECDSA", namedCurve: "P-256" }, true, ["sign"])
Uncaught Error

The imported bytes above represent a P-256 private key without the public key bytes (in hex: 308141020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207632de7338577bc12c1731fa29f08019206af381f74af60f4d5e0395218f205c). Here's a asn1js link to see the structure

@panva helped me run this case across multiple implementations, here are the results:

runtime result
Bun ✔️
Chromium DataError
Deno DataError
Firefox DataError
Node.js ✔️
WebKit DataError
Workerd DataError

See nodejs/node#50174 for context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions