Getting error "data too large for key size" with Crypto Node.js

12,555

RSA works by doing modular exponentiation. This means that anything that is encrypted will usually have as many bits as the modulus (which is the product of the two primes).

RSA needs a padding scheme to be secure. The default is RSA_PKCS1_OAEP_PADDING in node.js. This padding scheme adds 42 bytes to the plaintext before encryption, but now the new plaintext (first_result) is larger than the modulus and it will not be able to encrypt it in a recoverable manner.

You have two options:

Let's try disabling padding:

var first_result = crypto.privateEncrypt({
    key: first_keys.private_key
}, new Buffer("Hello World!"));

var second_result = crypto.privateEncrypt({
    key: first_keys.private_key,
    padding: constants.RSA_NO_PADDING
}, first_result);

var second_plaintext = crypto.publicDecrypt({
    key: first_keys.public_key,
    padding: constants.RSA_NO_PADDING
}, second_result);

var first_plaintext = crypto.publicDecrypt({
    key: first_keys.public_key
}, second_plaintext);
Share:
12,555
arturojain
Author by

arturojain

I devoted my life to media, content creation, and community management using low-budget technologies to compete against big corporations, achieving and exceeding my established — and own — goals. My experience has grown overtime by working in several projects gaining knowledge in design, marketing, photography, and, finally, a grade at University as an IT and systems engineer.

Updated on June 14, 2022

Comments

  • arturojain
    arturojain almost 2 years

    I'm getting the error "Error: error:0406C06E:rsa routines:RSA_padding_add_PKCS1_type_1:data too large for key size" when I do:

    var crypto = require('crypto');
    var fs = require('fs');
    
    var first_keys = {
        public_key: fs.readFileSync('tests/public.key'),
        private_key: fs.readFileSync('tests/private.key')
    }
    
    var first_result = crypto.privateEncrypt({
        key: first_keys.private_key
    }, new Buffer("Hello World!"));
    
    var second_result = crypto.privateEncrypt({
        key: first_keys.private_key
    }, first_result);
    
    var second_plaintext = crypto.publicDecrypt({
        key: first_keys.public_key
    }, second_result);
    
    var first_plaintext = crypto.publicDecrypt({
        key: first_keys.public_key
    }, second_plaintext);
    
    if(first_plaintext == new Buffer("Hello World!"))
        console.log("Hello World!");
    

    I know it is weird, but I'm creating a process that requires this to work for n iterations (private encrypting for n keys and public decrypting for n keys). I'm using a single key for testing purposes.

  • arturojain
    arturojain over 8 years
    Awesome, thank you. Any idea why when compering first_plaintext == new Buffer("Hello World!") it is not equal?
  • Artjom B.
    Artjom B. over 8 years
    Yes, because you need to use buf1.equals(buf2). Buffer is not a default JavaScript object, so it cannot be directly compared.
  • arturojain
    arturojain over 8 years
    Thank you, a lot. You're awesome.