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