views:

28

answers:

1

I've been playing around with Bouncy Castle's implementation of RSA (Lightweight API) and got the basics figured out. Looking at their spec for JCE provider implementation I noticed that different padding schemes can be used with RSA. From what I understand, by default null padding is used. So I began exploring OAEP padding, particularly OAEPWithSHA512AndMGF1Padding. Searching with Google wasn't very helpful so I began digging through BC's source code and found org.bouncycastle.jce.provider.JCERSACipher class. But looking at initFromSpec quickly gave me a headache... Specifically, I don't understand what the last two parameters that can be passed to the OAEPEncoding constructor are. According to BC's API the OAEPEncoding constructor that allows four parameters accepts Digest mgf1Hash and byte[] encodingParams as the last two arguments. This stumped me because I have no idea how to get a hold of an instance of the mask generation algorithm nor do I understand the purpose behind the byte array referred to as encodingParams. What should be the values of arg3 and arg4 in the code below?

RSABlindedEngine rsa = new RSABlindedEngine();
SHA512Diges sha512 = new SHA512Digest();
Digest arg3 = ???;
byte[] arg4 = ???;
AsymmetricBlockCipher cipher = new OAEPEncoding(rsa, sha512, arg3, arg4);
+1  A: 

OAEP is specified by PKCS#1, section 7.1.

OAEP requires the following parameters:

  • a hash function;
  • a "mask generation function" which can be thought of as a hash function with unlimited output length;
  • a "label" (an arbitrary sequence of bytes).

There is only one defined mask generation function, called MGF1, and that function is built over a hash function. So your arg3 is the hash function which MGF1 will use. It may be the same hash function than the first one (I am not sure it may be the same Digest instance in the Bouncy Castle API; I am talking mathematically here). It may also be another hash function.

The label can be used as a kind of distinguishers between instances (e.g. you could encrypt data with an explicit "purpose" encoded in the label). It is handy in some mathematical proofs, but right now PKCS#1 recommends using an empty string and be done with it. For the purposes described in PKCS#1, an empty label is as good as any.

The decryption process must know those parameters to operate. It is customary to encode them in the structure which comes along with the encrypted message and says "this is encrypted with RSA/OAEP"; that's how it happens in CMS.

When in doubt, use the same hash function as first parameter and for MGF1, and use an empty label.

Thomas Pornin
Thank you. Clear and concise, as usual. Quick follow up question, do you know if it's a good idea to reuse the same instance of a Digest object? Right now I have three separate instances: two that I pass into the OAEPEncoding encoding constructor and one to RSADigestSigner (for signing).
Andrey
@yamsha: it depends on the Bouncy Castle implementation. It is plausible that they do things in a natural, sequential order, in which case reusing the same Digest will work properly. It is equally plausible that creating new Digest instances has negligible cost. Just to be safe, I would recommend using distinct instances. But chances are that it has very little impact either way.
Thomas Pornin