16

Typically it is recommended that RSA be used to encrypt a symmetric key, which is then used to encrypt the "payload".

What is the practical (or theoretical) limit to the amount of data that can be encrypted with RSA (I'm using a 2048 bit RSA keysize).

In particular, I'm wondering if it is safe to encrypt an RSA public key (256 bytes) with a (different) RSA public key? I'm using the Bouncy Castle crypto libraries in Java.

sanity
  • 35,347
  • 40
  • 135
  • 226
  • Why are you encrypting an RSA public key? There's nothing to hide there. – WhiteFang34 Apr 07 '11 at 15:25
  • My RSA public key reveals my identity, and I don't want to do that except to the recipient. – sanity Apr 07 '11 at 15:45
  • The only situation that I can think of where one needs to do such a thing is if you want to send a public key to someone else and he be sure to get the correct one. So, you could be sending the public key, both unencrypted and encrypted with the receiver's public key so only he can decrypt it and compare it with the sent unencrypted one. – ypercubeᵀᴹ Apr 07 '11 at 15:47
  • @sanity: Yes, that too. Two situations. – ypercubeᵀᴹ Apr 07 '11 at 15:48
  • Technically an RSA public key is nothing more than 2 integers (a really big modulus and an exponent). You can leave out everything else associated with it and still encrypt something the private key holder can decrypt. – WhiteFang34 Apr 07 '11 at 16:02
  • Your public key only reveals your 'identity' insofar as the attacker can determine that multiple documents signed by the same key have the same signer. Why not just generate a new public/private key pair for this communication and use that? – Nick Johnson Apr 08 '11 at 04:10
  • @ypercubeᵀᴹ in your scenario the receiver cannot be sure that he gets a correct one. anybody can take his public key, encrypt it and send him that incorrect replacement instead. what you probably meant was signing it with the private key of the sender so that the receiver can verify the signature and thus the authenticity – Palo Mar 30 '16 at 15:24
  • @Palo thnx, yes. I was obviously confused when writing that comment! – ypercubeᵀᴹ Mar 30 '16 at 17:09

4 Answers4

22

For a n-bit RSA key, direct encryption (with PKCS#1 "old-style" padding) works for arbitrary binary messages up to floor(n/8) - 11 bytes. In other words, for a 1024-bit RSA key (128 bytes), up to 117 bytes.

With OAEP (the PKCS#1 "new-style" padding), this is a bit less. OAEP uses a hash function with output length h bits; this implies a size limit of floor(n/8) - 2*ceil(h/8) - 2. For a 1024-bit RSA key using SHA-256 as the hash function (h = 256), this means binary messages up to 62 bytes.

There is no problem in encrypting a RSA key with another RSA key (there is no problem in encrypting any sequence of bytes with RSA, whatever those bytes represent), but, of course, the "outer" RSA key will have to be bigger: with old-style padding, to encrypt a 256-byte message, you will need a RSA key with a modulus of at least 2136 bits.

Hybrid modes (you encrypt data with a random symmetric key and encrypt that symmetric key with RSA) are nonetheless recommended as a general case, if only because they do not have any practical size limits, and also because they make it easier to replace the RSA part with another key exchange algorithm (e.g. Diffie-Hellman).

Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
  • @ thomas-pornin I wasn't aware of these limits on RSA. I don't have access to my crypto references right now, could you tell me where you found this information? – AVH Apr 07 '11 at 19:54
  • 2
    @Darhuuk: the limits follow quite plainly from how the padding systems work; and they are stated quite plainly in PKCS#1 (page 18 for OAEP, page 23 for old-style padding). – Thomas Pornin Apr 07 '11 at 20:01
  • 2
    Isn't floor(1024/8)-2*ceil(256/8)-2 == 62 instead of 60? – Tien Jul 24 '19 at 09:08
  • @ThomasPornin are you able to help with https://stackoverflow.com/questions/70997010/manually-decrypt-the-signature-in-a-digital-certificate ? – David Klempfner Feb 05 '22 at 10:45
3

The limit is more or less infinite, but as you say yourself, this is not how asymmetric crypto should be used. The methods used to implement an asymmetrical crypto system are orders of magnitude slower than those for symmetric crypto (such as AES, TrippleDES, PRESENT, ...). So why would you do that? Use your asymmetric crypto to establish a key (using a secure key establishment protocol, don't invent one) and then encrypt your data with a symmetric algorithm using the established key.

On an related note: why would you encrypt with another public key? As the name says, it's supposed to be public. An attacker can't do anything with it if he gets his hands on it.

[Edit] One thing you should definitely check is if the functions you use implement padding (preferably RSAES-OAEP). Otherwise your public key will encrypt to the same output every time and thus an adversary spying in on your communication can still learn that it is you who is transmitting something, even though he can't see which public key it is you are transmitting.

AVH
  • 11,349
  • 4
  • 34
  • 43
  • Well, I understand it is much slower, but it would be an infrequent operation, and I'm only encrypting 256 bytes. I'm wondering if its worth worrying about. To your question: I want to encrypt it as my public key reveals my identity, and I would prefer not to do that except to the recipient. – sanity Apr 07 '11 at 15:43
  • @sanity I see, well, in that case the overhead from establishing a key is probably not worth it. So I guess you might as well encrypt with RSA then. – AVH Apr 07 '11 at 15:45
  • thanks - I assume you are fairly confident about that? (ie. should I bother testing it?) – sanity Apr 07 '11 at 15:46
  • @Sanity Well, testing can't hurt, can it :)? Also see edit in my answer for some extra info. – AVH Apr 07 '11 at 15:50
2

The (theoretical) limit is infinite.

For the practical limit, you'll have to make tests with your particular hardware/software implementation and compare to your requirements regarding speed.


Regarding safety, I'd say yes. Your identity (that you want hidden) is as safe as your recipient's private key's safety.

ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235
0

Three years after you asked the question, I stumbled across your posting, because I just had to implement something similiar. What you will need in this case is an encryption mode to break the message into key sized chunks, because of the maximum message length. You will also need block padding to pad each block of the message (oposed to message padding that is usually applied to something like DES,3DES,AES). Not easy, but possible. You need to make sure that each padded block is smaller than the maximum allowed size. For block padding you could use for example OAEP or PKCS_V1_5. As encryption mode you could use ECB (not secure but works) or something more elaborated. (see wikipedia and encryption modes).

if you have a good crypto API you should be able to set the encryption mode and block/message padding and just throw the message at it.

Andy
  • 1
  • 1
  • 2
    Why would you encrypt a long message with RSA? The standard choice is hybrid encryption - encrypting the message with AES and the AES key with RSA. You can't use typical block-cipher encryption modes either, for example the xor step in CBC is obviously broken. – CodesInChaos Mar 20 '14 at 08:46