Sitelet https://github.com/nodejs/node/issues/46102
Skip to content

generateKeyPairSync implicitly changes odd to even modulusLength #46102

Description

@Neumann-Nils

Version

v18.12.1

Platform

Darwin G76106VXHK 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct 9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000 arm64

Subsystem

No response

What steps will reproduce the bug?

Simply try to create a keypair with an odd modulusLength:

const { generateKeyPairSync } = require('crypto');
const keypair = generateKeyPairSync('rsa', {
  modulusLength: 2049,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
  }
});
console.log(keypair);

This creates a key pair with 2084 length instead of 2049 as specified by the modulusLength (checked via openssl rsa -text -noout -in private.key). I can reproduce this issue with other odd modulusLength as well.

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

The bug can be reproduced consistently.

What is the expected behavior?

I would expect that a key pair with the odd input modulusLength (e.g., 2049) is generated.

What do you see instead?

A key pair with the "next" even modulusLength (e.g., 2048) is generated.

Additional information

The problem can be reproduced in node v18. In contrast, node v16 (e.g., 16.19.0) creates key pairs with odd modulusLength just fine.

Activity

  1. added
    cryptoIssues and PRs related to the crypto subsystem.
    opensslIssues and PRs related to the OpenSSL dependency.
    on Jan 5, 2023
  2. bnoordhuis commented on Jan 5, 2023

    @bnoordhuis
    Member

    I'm 95% sure this is related to the upgrade to openssl v3 in node v18.x; its RSA_generate_multi_prime_key() function rounds down the modulus by dividing it by the number of primes (default: 2):

    /* divide bits into 'primes' pieces evenly */
    quo = bits / primes;
    rmd = bits % primes;

    It's basically expected behavior in other words. Pre-empting "shouldn't this be documented?" comments, I'd be interested to know why you're creating odd digit keys. Seems like an odd (hah!) thing to do.

  3. panva commented on Jan 5, 2023

    @panva
  4. Neumann-Nils commented on Jan 5, 2023

    @Neumann-Nils
    Author

    @bnoordhuis Thanks for your quick response. There is no real use-case, we are just using an odd modulusLength in some of our integration tests (and that's how we noticed it). There is no problem with changing it to another even modulusLength.

  5. panva commented on Jan 5, 2023

    @panva
    Member

    Yeah, ignore my above hidden comment. The modulusLength is generated as described, with 1.1.1 odd is possible, with 3.x it is not as it rounds down because of the reasons @bnoordhuis pointed out.

    3.x still does 2047 tho...

    On an unrelated note, KeyObject.prototype.asymmetricKeyDetails always returns a ceiled multiple of 8 value (BN_num_bits(n) * CHAR_BIT). Do we want to do something about it (#46106)?.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.opensslIssues and PRs related to the OpenSSL dependency.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions