The Java algorithm string "RSA/ECB/PKCS1Padding"
, as you already found out, does not implement ECB; it only encrypts/decrypts a single block. The Bouncy Castle cryptographic security provider has a better named algorithm string, "RSA/None/PKCS1Padding"
, which better indicates that no mode of operation is used. It is likely that "/ECB"
was just included to mimic the cipher string for block ciphers. So you would have to call the cipher "RSA/ECB/PKCS1Padding"
multiple times to implement ECB.
"PKCS1Padding"
indicates RSA with PKCS#1 v1.5 padding for encryption. This padding is indeterministic - i.e. it uses a random number generator. This explains why each ciphertext block will be different.
To make RSA secure it is required to use a secure padding scheme. If PKCS#1 v1.5 padding is used then there is a significant (11 byte) overhead for each block of plaintext. The padding consists of at least eight bytes of positive random values which explains why the ciphertext is always different even if the same plaintext block is encrypted. If you would use RSA in ECB mode then you would end up losing the padding overhead for each block. That means that the ciphertext would be significantly larger than the plaintext.
Furthermore, RSA operations require a lot of CPU resources. The RSA encryption/decryption operations are based on modular exponentiation with extremely large numbers. Using RSA operations on many blocks will therefore use a lot of CPU time. This is especially true for decryption; encryption has the advantage that the public exponent is generally relatively small. But even RSA encryption will be a lot more CPU-expensive than any symmetric cipher.
To encrypt larger messages you should be using a hybrid cryptosystem where asymmetric (RSA) encryption is paired with a fast, efficient symmetric cipher such as AES. In your case where you encrypt a large amount of numbers it is better to aggregate them in a structure, encrypt the structure using AES and then encrypt the AES key using your RSA public key.
Notes:
- OAEP is more secure than PKCS#1 padding. If you choose OAEP then the padding overhead is even larger, making ECB even less efficient;
- It is also possible to use RSA-KEM or any other technique to establish the symmetric key - those techniques are however not present in the Java JCA library as of now;
- For block ciphers ECB performs the block cipher operation for each block in the plaintext. This is not secure in most situations, independent of the padding used. It is however useful as a lower level operation such as key wrapping of a symmetric key;
- Instead of designing your own protocol you could be using container formats such as the Cryptographic Message Syntax (CMS) or Pretty Good Privacy (PGP); both formats already implement a hybrid cryptosystem;
- Increasing the key size only to support larger messages is generally not recommended: it would require a huge increase of CPU time during encryption and decryption, only dwarfed by the time it takes to generate the larger RSA key pair;
- You may want to sign the message before encryption for additional security (sometimes it makes more sense to sign afterwards, it depends on the use case);
- Using all possible bytes for PKCS#1 v1.5 padding comes with a downside: the random padding is only ~64 bits so there is a possibility of a collision with an earlier padding due to the birthday bound - it is better to use an overhead of 19 bytes instead of 11 bytes and have ~128 bits of padding.