Skip to content

Running under node, io.js does not properly pass OAEP hash and label parameters to crypto.publicEncrypt() #229

Open
@tonesandtones

Description

@tonesandtones

The problem

When running in a Node process, encrypting with PKCS1 OAEP padding with custom label and SHA 256 hash algorithm, io.js does not pass the OAEP hash and OAEP label parameters to crypto.publicEncrypt().

Expected behaviour

When run in a node process, OAEP padding is applied with the chosen hash function and label before being encrypted.

Actual behaviour

OAEP padding is applied with node crypto defaults of SHA1 and no label instead of the requested hash and label. See https://nodejs.org/api/crypto.html#cryptopublicencryptkey-buffer

image

The cause

When running in a node process, node-rsa selects an encrypt engine wrapper encryptEngines/io.js or encryptEngines/node12.js. Neither passes the configured oaep hash or label to crypto.publicEncrypt().

Workaround

When specifying your NodeRSA options object, set environment: 'browser' to cause node-rsa to select the encrypt engine encryptEngines/js.js, which implements is own oaep padding.

Example workaround

//MUST set environment: 'browser'. When run with environment == 'node' (or autodetected
//to be running in a node process), node-rsa doesn't properly pass the oaep hash and
//label parameters to node crypto and defaults to SHA-1 and no label.
//Using 'browser' causes node-rsa to use its own OAEP implementation and uses the hash
//and label parameters correctly.
const options = {
    environment: 'browser', //CRIITICAL - MUST BE 'browser'
    encryptionScheme:{
        hash: 'sha256', //message and mgf1 hash function
        label: '<OAEP padding label>', //oaep padding label, a.k.a. encoding parameter
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
    }
};

const key = new NodeRSA(undefined, options); //set the current key to undefined so it doesn't try to create a new public/private keypair

const rsaMod = '<long modulus component>';
const rsaExp = '<short exponent components>';

//now import the public component of our key
key.importKey({
    n: Buffer.from(rsaMod, 'hex'),
    e: Buffer.from(rsaExp, 'hex')
}, 'components-public');

const encryptedBuffer = key.encrypt(Buffer.from('<message to encrypt>'), 'buffer');

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions