On Feb 18, 2013, at 10:17 AM, Nikola <[email protected]> wrote:
> I've sent you all necessary details to reproduce the NullReference exception.

Thank you. I'll investigate this tomorrow.

>> I'm told by the resident SSL expert ... and this RSA instance will be used 
>> in the SSL handshake logic. 
...
> The last line fails with the following horrible exception:
> 
> System.Net.WebException: ... ---> Java.Lang.ArrayIndexOutOfBoundsException: 
> Exception of type 'Java.Lang.ArrayIndexOutOfBoundsException' was thrown.
...
> java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
>  at 
> com.android.org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(JCERSACipher.java:450)
>  at javax.crypto.Cipher.doFinal(Cipher.java:1111)
...

As with many things in Android, you need to (1) read _very_ carefully, and (2) 
frequently need to dig into the Android source code.

Regarding (1), the error is that you're passing "too much data for RSA block."

Regarding (2), having an AOSP source checkout is invaluable...

        http://source.android.com/source/index.html

JCERSACipher.java:450 leads us ~here: 
http://www.docjar.org/html/api/org/bouncycastle/jce/provider/JCERSACipher.java.html#441

          449                   throw new ArrayIndexOutOfBoundsException("too 
much data for RSA block");

(What's a line or ten among friends and URI anchors?)

In short, I don't think you can pass the entire buffer to DoFinal(byte[]) as 
you're doing in CustomRSA.DecryptValue() and CustomRSA.EncryptValue(). I 
believe you'll need to do it "piecewise", presumably with (repeated?) calls to 
Cipher.Update(byte[]):

        
http://developer.android.com/reference/javax/crypto/Cipher.html#update(byte[])

Alternatively (relatedly?):

1. The exception could be due to the use of the wrong API: .NET DecryptValue() 
is a "raw" (unpadded) decryption (which is what is required here since SSL has 
it's own padding
requirements), while Decrypt expect a padded input;

2. Endianness: some BigInteger library reverse the byte stream

> I am not really sure why the Mono.Security.Cryptography.PKCS1.Sign_v15 method 
> calls the CustomRSA.DecryptValue method - I would expect that signing would 
> involve encryption of bytes, not their decryption.

Quoting my SSL expert:

The fact that DecryptValue is called is normal; it's a bit misleading but RSA 
is foremost used for encryption so those name are used in the API, e.g.

Encryption: anybody (public) can encrypt something only you (private) can 
decrypt.

So the API is named:
* Encrypt: when using the public key
* Decrypt: when using the private key

Signature: only you (private) can sign a document that anybody (public) can 
verify.

Reusing the same API you find yourself using Decrypt to sign :-)

In short, it looks like your RSA class is correct, semantically, it's the 
implementation that is not (as Java is complaining about how you're calling it).

 - Jon

_______________________________________________
Monodroid mailing list
[email protected]

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to