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

Cannot encrypt to an RSA 512-byte key #398

Closed
DavidAnderson684 opened this issue May 12, 2016 · 4 comments
Closed

Cannot encrypt to an RSA 512-byte key #398

DavidAnderson684 opened this issue May 12, 2016 · 4 comments

Comments

@DavidAnderson684
Copy link

DavidAnderson684 commented May 12, 2016

var pubkey = "-----BEGIN PUBLIC KEY-----\
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALLhH5+o8H92pAmY1mV6X4dWGFo2q4+P\
yYviDSW4uauXgyUCDZ08mH4NllVBzSEZ35v1EuV/VteqJjhNxX5GVYECAwEAAQ==\
-----END PUBLIC KEY-----";

var bytes = "12345678901234567890123456789012";
var sym_key = pubKey.encrypt(bytes, 'RSA-OAEP');

The result is:

RSAES-OAEP input message length is too long

This apparently comes from:

var error = new Error('RSAES-OAEP input message length is too long.');
. It seems that I can't encrypt more than 22 bytes.

Using the same key pair with phpseclib works.

Am I misunderstanding something important here, or is this a bug? I know that the RSA key size limits how many bytes you can encrypt... but the fact that phpseclib is happy with it, and that it's not mentioned in the JSDoc on the method signature, is puzzling me.

I realise, of course, than 512 bit keys aren't a good idea. But, we support a user-choosable key size, which allows the user to choose a 512 bit key if he's stuck with a web hosting company with missing PHP modules and consequent very slow key generation (we're generating the keys in phpseclib on the back-end), which allows them to take ownership of their problem (ideally, they'd install the missing PHP modules) - and also allows for when the transport is already protected by https and they don't need a large key. (This is a WordPress plugin, and we've got to cover all the various setups people have out there).

@dlongley
Copy link
Member

RSAES-OAEP can operate on messages of
length up to k - 2hLen - 2 octets, where hLen is the length of the
output from the underlying hash function and k is the length in
octets of the recipient's RSA modulus.

https://tools.ietf.org/html/rfc3447#section-7.1

A 512-bit key is 64 bytes in size (k=64). If you're using SHA-256, the hash length is 32 bytes (hLen=32):

k - 2hLen - 2 = 64 - 2 * 32 - 2 = -2 -- you can't encrypt at all using SHA-256.

If you're using SHA-1, which has a hash size of 160 bits or 20 bytes (hLen=20):

k - 2hLen - 2 = 64 - 2 * 20 - 2 = 22 -- you can't encrypt more than 22 bytes using SHA-1.

A better way to encrypt an arbitrary amount of data using RSA is to produce a random symmetric key, use AES-GCM to encrypt your data with it, and then encrypt just the symmetric key with RSA. In this case, you could use an AES-128 bit key (16 bytes) and it would fit. However, note that RSA 512 is considered totally insecure; you should be using at least 2048 bits.

@DavidAnderson684
Copy link
Author

Thank you for taking the time. I am using a random symmetric key to encrypt arbitrary data; it just happens to be a 32 byte long key; I will use a shorter one.

I was curious about what it is that phpseclib is doing when it's apparently successfully using one. Perhaps splitting and chaining? Obviously, though, that's not a question for you.

"However, note that RSA 512 is considered totally insecure" - I explained that bit in my final paragraph.

Thanks again!

@dlongley
Copy link
Member

Sure! Yeah, I don't know what phpseclib is doing... :)

I'm going to close this out, feel free to re-open if there's a reason to.

@T3chTobi
Copy link

@dlongley Hi, I need help for my thesis!

I'm signing a message:
var md = forge.md.sha1.create();
md.update('my_random_aes_key', 'utf8');
var signature = privateKey.sign(md);

And trying to encrypt this signature:
var encrypted = publicKey.encrypt(signature);

But at the encryption I get following error message: Error: Message is too long for PKCS#1 v1.5 padding or RSAES-OAEP input message length is too long

How can I encrypt a message AND its signature? (I can't even encrypt the signature on its own...)

To combine the message AND its signature should I use an object like following?
var obj = {
message: msg,
signature: signature,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants