The point is that it's using ECB mode with RSA, which indicates the developer has no real knowledge of crypto and is just blindly using pairs of "encrypt/decrypt" functions from Node's built-in crypto lib (which is essentially a thing wrapper around OpenSSL and thus joins its illustrious legacy of encouraging developers to make catastrophic cryptographic implementation mistakes).
In encryptMessage.js, the plaintext is split into chunks, and then chunks.forEach encrypts each chunk (via crypto.publicEncrypt) independently, and concatenates the chunks to form the ciphertext, aka ECB mode. You shouldn't use ECB mode with any cipher because it is not semantically secure. This is Crypto 101.
In addition, it's a bit wacky to use RSA encryption on your entire message because RSA operations are slow and you are limited to encrypting messages that are the length of your RSA key (well, minus the padding, which is how this developer arrived at the "split plaintext into 214 byte chunks" workaround).
A better solution (in every way) would be to use a "hybrid" encryption scheme, similar to TLS or GPG. To do this, you would:
1. Generate a random key for use with a symmetric cipher (e.g. AES-256)
2. Encrypt the plaintext with the random key, using a secure block mode (e.g. CBC, CTR)
3. Encrypt the random key with the RSA public key
4. Package those things together and share it on Github
Efficient and secure. Also totally unnecessary (you basically just reinvented a subset of GPG) but that's neither here nor there.
I love this comment. Thank you for putting the time in to proposing a more thorough solution. I will take this (and other) comments into consideration, and make some much needed improvements :)
There are a whole bunch of things you're likely to get wrong trying to design your own "hybrid" encryption system. It's not easy. Why not spend some time learning how to break crypto before you start building it?
I agree. There are whole classes of problems that are not at all obvious until one has spent time learning how to break bad crypto. Matasano's challenges[0] (which I think tptacek helped create) are a good start.
It appears to be using Node's crypto library to apply the RSA transform directly to the plaintext in modulus-size chunks. The problem isn't the quality of the RSA implementation.
In encryptMessage.js, the plaintext is split into chunks, and then chunks.forEach encrypts each chunk (via crypto.publicEncrypt) independently, and concatenates the chunks to form the ciphertext, aka ECB mode. You shouldn't use ECB mode with any cipher because it is not semantically secure. This is Crypto 101.
In addition, it's a bit wacky to use RSA encryption on your entire message because RSA operations are slow and you are limited to encrypting messages that are the length of your RSA key (well, minus the padding, which is how this developer arrived at the "split plaintext into 214 byte chunks" workaround).
A better solution (in every way) would be to use a "hybrid" encryption scheme, similar to TLS or GPG. To do this, you would:
1. Generate a random key for use with a symmetric cipher (e.g. AES-256) 2. Encrypt the plaintext with the random key, using a secure block mode (e.g. CBC, CTR) 3. Encrypt the random key with the RSA public key 4. Package those things together and share it on Github
Efficient and secure. Also totally unnecessary (you basically just reinvented a subset of GPG) but that's neither here nor there.