Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faulty export for RSA-PSS public keys from node:crypto to webcrypto #49141

Closed
koteisaev opened this issue Aug 13, 2023 · 5 comments
Closed

Faulty export for RSA-PSS public keys from node:crypto to webcrypto #49141

koteisaev opened this issue Aug 13, 2023 · 5 comments
Labels
crypto Issues and PRs related to the crypto subsystem. webcrypto

Comments

@koteisaev
Copy link

Version

18.17.1

Platform

Microsoft Windows NT 10.0.22621.0 x64

Subsystem

node:crypto

What steps will reproduce the bug?

RSA-PSS key generation

        let [publicKey, privateKey] = await new Promise<[KeyObject, KeyObject]>((resolve, reject) => {
            let processGeneratedKeys = (err:Error, publicKey:KeyObject, privateKey:KeyObject) => {
                                err ? reject(err) : resolve([publicKey, privateKey]);
                            };

generateKeyPair('rsa-pss', {
                            modulusLength: 4096,
                            publicExponent: 0x010001,
                            hashAlgorithm: "sha512",//algo.hash || DigestAlgorithm.SHA512,
                            saltLength: 64 as any // algo.saltLength.bytes as any
                        }, processGeneratedKeys);

The saltLength in parameters type definition somehow is string so had to use the as any trick here. But it seems does not affect the problem.

public key exporting code

data = this.#impl.export({
                    type: "spki",
                    format: 'der'
                });

Import code in "browser emulator" with webcrypto

return await this.crypto.subtle.importKey('spki', data, {
                    name: 'RSA-PSS',
                    hash: "SHA-512". // algo.hash,
                }, !!extractable, ["verify"]);

How often does it reproduce? Is there a required condition?

It always reproduced, and checked by other person I don't know.

What is the expected behavior? Why is that the expected behavior?

Expected behavior is exporting a RSA-PSS public key as RSA-PSS SPKI DER by PublicKeyobject.export that it can be successfully imported with the webcrypto.

What do you see instead?

Instead i see the following error on importKey call:

DataError: Invalid key type
    at new DOMException (node:internal/per_context/domexception:53:5)
    at __node_internal_ (node:internal/util:520:10)
    at Object.rsaImportKey (node:internal/crypto/rsa:293:11)
    at SubtleCrypto.importKey (node:internal/crypto/webcrypto:611:10)
    // rest of call stack is part of Mocha test context etc.

Additional information

I asked this question at StackOverflow: https://stackoverflow.com/questions/76891595/domexception-invalid-key-type-from-webcrypto-importkey-on-rsa-pss-public-key-in?noredirect=1#comment135553831_76891595

I got following comment: https://stackoverflow.com/questions/76891595/domexception-invalid-key-type-from-webcrypto-importkey-on-rsa-pss-public-key-in?noredirect=1#comment135553831_76891595

I can reproduce the issue. The import fails for PSS with the webcrypto NodeJS integration (but is successful for PKCS#1), here. In contrast, the import with webcrypto in the browser is successful for PSS, here (works with Firefox, but not with Chrome (which is a browser problem though)). This points to a bug in the webcrypto NodeJS integration. You could file a NodeJS issue for that.

Providing it here as hope it will make this bug report more helpful.

@panva
Copy link
Member

panva commented Aug 13, 2023

The webcrypto specification (live editor's draft at https://w3c.github.io/webcrypto/) no longer supports alternative OIDs on the account of their support never being properly implemented by implementors.

Relevant PR on webcrypto's spec w3c/webcrypto#325

In other words, the crypto export is not faulty but the webcrypto import intentionally rejects the key material because RSA-PSS OID keys were ONLY supported by Node.js (but not correctly wrt roundtrip export/import), Deno and partially (but not correctly checking parameters) in Gecko tye specification (and our implementation) was updated to reflect the actual observable interoperable behaviour which is to not support the non-generic OIDs such as RSA-PSS, RSA-OAEP, and others.

@panva panva added crypto Issues and PRs related to the crypto subsystem. webcrypto labels Aug 13, 2023
@bnoordhuis
Copy link
Member

@panva do I interpret that correctly as "wontfix, working as intended"?

@koteisaev
Copy link
Author

koteisaev commented Aug 19, 2023

@panva and how then I should export RSA-PSS public keys to be imported/used by browser? How I should test this kind of export-import with webcrypto of node:crypto? Can I use standard RSA public keys (generated with algorithm specifier rsa) in RSA-PSS mode both at node and import as rsa-pss at browser? How I can test this scenario?
Why then RSA-OAEP works as expected in both directions between webcrypto and standard node:crypto API? By this logic both should work or both should fail same way?

@panva
Copy link
Member

panva commented Aug 20, 2023

@bnoordhuis correct, this is wontfix working as intended.

@koteisaev the webcrypto algorithm identifiers and node crypto keygen identifiers do not map to the same key material OIDs. I also talked about OIDs in my previous comment, not algorithms. You can certainly use plain old generic rsaEncryption key material for signing and verifying RSA-PSS signatures with both webcrypto and node crypto.

@panva panva closed this as not planned Won't fix, can't repro, duplicate, stale Aug 20, 2023
@koteisaev
Copy link
Author

@panva Thanks for clarification.
Side note for those who will find this thread by Kagi or Google search:

  • generate RSA keys only with rsa mode at node side, not rsa-pss.
  • at WebCripto side, still specify RSA_PSS, RSASSA-PKCS1-v1_5 and RSA-OAEP depending on how you will use the key, on key generation or import. These parameters must match on calls to verify, sign, 'encryptanddecrypt. WebCrypto is more strict on this, so you can not sign using RSA-PSSmode if key generated at WebCrypto or imported asRSASSA-PKCS1-v1_5ofRSA-OAEP` at WebCripto side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crypto Issues and PRs related to the crypto subsystem. webcrypto
Projects
None yet
Development

No branches or pull requests

3 participants