-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Description
Version
v20.8.0
Platform
MacOS
Subsystem
crypto
What steps will reproduce the bug?
In Node console:
$ 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 (tried both Firefox and Chrome):
> 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
Additional information
The bytes I'm importing are, in hex format: 308141020100301306072a8648ce3d020106082a8648ce3d0301070427302502010104207632de7338577bc12c1731fa29f08019206af381f74af60f4d5e0395218f205c
You can use asn1js to decode this pkc8 structure: https://lapo.it/asn1js/#MIFBAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBCcwJQIBAQQgdjLeczhXe8EsFzH6KfCAGSBq84H3SvYPTV4DlSGPIFw
This is a P-256 private key with no public key bytes (they are optional in pkcs8)
I'm honestly not sure that browsers are doing the right thing here but at the very least this behavior ("error when no public key bytes are present") seems intentional: Chrome has an explicit test case for it:
// The private key is exactly equal to the order, and the public key is
// omitted.
{
"crv": "P-256",
"key_format": "pkcs8",
"key": "3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
"error": "DataError"
},
This specific private key (from the test case) also succeeds in NodeJS:
// This is `3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551`
buffer = new Uint8Array([48,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,255,255,255,255,0,0,0,0,255,255,255,255,255,255,255,255,188,230,250,173,167,23,158,132,243,185,202,194,252,99,37,81])
> 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' ]
}