13

I need to decrypt messages via RSA in order to send it over an unsecured channel, but I'm afraid of the Padding Oracle Attack. Therefore I already have asked the follwoing questions:

  1. How to verify the integrity of RSA encrypted messages?
  2. How to ensure message integrity for RSA ciphers by using javax.crypto.Cipher

Like suggested in the first question,

However, since you are using a high level cryptographic library, this is something you shouldn't have to worry about. The writers of that library should have taken care of it.

I shouldn't consider about. As far I know, the RSA implementation of PKCS#1 v1.5 is vulnerable to the Padding Oracale Attack whereby OAEP isn't (assumed it's implemented correctly)

Hence I want to know which padding implementation is used by javax.crypt.Cipher by Java 7

Community
  • 1
  • 1
My-Name-Is
  • 4,814
  • 10
  • 44
  • 84
  • 2
    This would depend on the provider, but is most likely PKCS1Padding (PKCS#1 v1.5 padding). To clarify, you're asking what padding is used when you don't fully qualify the cipher as in `Cipher.getInstance("RSA")`? – Artjom B. Aug 16 '15 at 09:57
  • @ArtjomB Yes, exactly. But I would use a different one like BouncyCastle if it would be more secure. – My-Name-Is Aug 16 '15 at 10:02
  • 3
    If you want a specific padding scheme, you should *specify* it, instead of relying on a default, especially when you don't know what it is. – user207421 Aug 16 '15 at 10:11

3 Answers3

20

It depends on the chosen or default provider which padding is actually used when you instantiate a Cipher without fully qualifying it like:

Cipher.getInstance("RSA")

Doing so is a bad practice, because if you switch Java implementations, there might be different defaults and suddenly, you won't be compatible with the old ciphertexts anymore. Always fully qualify the cipher.

As I said before, the default will probably (there are many providers, one can't be sure) be PKCS#1 v1.5 padding. If you need another, you would have to specify it. If you want to use OAEP, here is a fully qualified cipher string from here:

Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • 1
    Heh, posted within 10 secs from each other :) Answers nicely in sync too. Good idea to include the OAEP string. – Maarten Bodewes Aug 16 '15 at 10:14
  • I've written the answer and skimmed through the [paper](http://archiv.infsec.ethz.ch/education/fs08/secsem/Manger01.pdf) linked from wikipedia on the OAEP padding oracle attack. Then I've seen EJP's comment and thought better post now before somebody tries to squeeze in ;) – Artjom B. Aug 16 '15 at 10:17
  • @ArtjomB. Thx, for the great answer. I just want to know if I have to use `ECB` for encryption mode. The usage of `ECB` in AES encryption is known to be vulnerable because of the missing redundancy. But here with RSA `ECB` gives differnent ciphers for the same plaintext! Why? Shouldn't the encryption mode `CBC`?. I think that `GCM` can't be used since there's no common key for the creation of the HMAC. – My-Name-Is Aug 16 '15 at 10:30
  • 3
    @My-Name-Is RSA doesn't use a mode of operation such as ECB or CBC. It is contained in the string for historical reasons, but the proper name would be `Cipher.getInstance("RSA/None/OAEPWithSHA-256AndMGF1Padding");` which I believe the BouncyCastle provider supports: http://stackoverflow.com/a/23888246 – Artjom B. Aug 16 '15 at 10:33
  • 3
    Besides that, the output of a cipher should be indistinguishable from random, even for different calls to the cipher with the same key. That's why you need an IV for CBC mode encryption and why ECB mode is insecure. As Artjom already indicated RSA/ECB is really RSA/None even in the Sun implementation. If it was ECB you would expect to encrypt a complete plaintext, whatever size it has. Now you should use a [hybrid cryptosystem](https://en.wikipedia.org/wiki/Hybrid_cryptosystem) unless you use truly small messages. – Maarten Bodewes Aug 16 '15 at 10:36
  • @MaartenBodewes Thx, I just don't understand why I should now switch to a hyprid cryptosystem. Is the "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" insecure? – My-Name-Is Aug 16 '15 at 10:46
  • 1
    @My-Name-Is It's secure. It's just that you can't encrypt arbitrarily long data with RSA. RSA can only encrypt something that is smaller that its modulus in bytes. If you have a 2048 bit RSA key, then you can only encrypt 2048 bit minus 42 byte (reserved for padding) equals 214 byte. To actually encrypt bigger plaintexts, you would encrypt it with a symmetric cipher and then encrypt the random symmetric key with RSA. – Artjom B. Aug 16 '15 at 10:50
  • 1
    To make it complete, if you also need integrity/authenticity, you should probably go for RSA-PSS sign using SHA-256, then GCM encrypt it with a random key and IV (prefix the IV), then encrypt the GCM key using OAEP (and hope that the OAEP implementation is secure). RSA-KEM is also great, but not implemented in Oracle's Java. Aint crypto fun :) – Maarten Bodewes Aug 16 '15 at 10:57
  • @ArtjomB. Thx for clarification! I'm aware of that, hence the prototype implementation uses keys of length 8192. Thats the reason why I switched to AES and there I got faced with the `Padding Oracle`. I'm pretty sure that the AES algorithm will be uesd, and with this question I just wanted to straighten out this (for me unclear) issue. I want to thank all of you for that great answers and I'm really sorry that it isn't possible to mark more than one question as accepted. THX! – My-Name-Is Aug 16 '15 at 11:01
9

That's not a good advice given in the first link to the cryptography site. You should never rely on the defaults of cryptographic libraries cryptographic algorithms. There are quite a few reasons for this:

  1. Different implementations, different defaults (there are no requirements for cryptography providers concerning defaults, although most will copy the Oracle/Sun defaults);
  2. What's secure now may not be considered secure tomorrow, and because for backwards compatibility, you can never change the default;
  3. It's unclear to anybody reading your software what the default is (you could document it, but in that case you might as well write it out).

The SunJCEProvider provided by Oracle defaults to PKCS#1 padding ("PKCS1Padding") for historical reasons (see reason #2 above). This is not well documented.

At that time that default was set you basically had just the insecure textbook RSA ("NoPadding") and the PKCS#1 v1.5 version ("PKCS1Padding" or RSAES-PKCS1-v1_5 in the PKCS#1 v2.1 standard). At that time RSAES-PKCS1-v1_5 was definitely the more secure choice. Changing the default now to OAEP would break every RSA implementation out there that uses the default.

The advice of otus (in the first link within this answer) is be better suited to protocol implementations in libraries than to cryptographic algorithms. In the end you should be able to defend the security of the choices made, whatever you choose.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
0

The default for bouncy-castle when you just specify RSA is RSA/NONE/NOPADDING

This is the same result as RSA/ECB/NOPADDING as well.

Idan Str
  • 614
  • 1
  • 11
  • 33
Lord Moon
  • 23
  • 5