Search code examples
blackberrycryptographyrsabouncycastlepublic-key-encryption

BouncyCastle J2ME RSA using custom keys


I would like to use BouncyCastle J2ME/RIM Crypto in my Blackberry Application.

The issue i'm having is that I would like to generate the public key for encryption from a C#.NET program that sends the key to the BlackBerry.

Is it possible to encrypt a message using a raw string? Also, do I need to know other common variable such as modulo etc? Apologies but i'm completely new to cryptography algorithms.

Do I need BouncyCastle for this or can the above be done with RIM Crypto?

Thanks, Conor


Solution

  • An RSA public key consists of two components, not just one like I thought.

    There is the Exponent and Modulus. These are both number but I pass them to the Blackberry from .NET client as Base64 strings and decode them into byte arrays when be used by the RIM Crypto function as they take Byte arrays as parameters.

    byte[] exponent = Base64InputStream.decode("exponent base64 string");
    byte[] modulus = Base64InputStream.decode("modulus base64 string");
    
    NoCopyByteArrayOutputStream cipherUserData = new NoCopyByteArrayOutputStream();             
    RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024);
    
    // Create Public key using your variables from before
    RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, exponent, modulus);
    
    // Encryption engine objects
    RSAEncryptorEngine eEngine = new RSAEncryptorEngine(publicKey);
    PKCS1FormatterEngine fEngine = new PKCS1FormatterEngine(eEngine);
    BlockEncryptor cryptoStream = new BlockEncryptor(fEngine, cipherUserData);  
    
    
    // Read the user data and encrypt while doing so. Remember, cryptoStream writes its data to
    // cipherUserData so this is where the encrypted version of userData will end up.
    cryptoStream.write( userData, 0, userData.length );
    
    cryptoStream.close();
    cipherUserData.close();
    
    String encryptedUserData = new String(cipherUserData.toByteArray());
    

    That's pretty much all there is too it folks, it's straightforward but it took me a long time to get this from the API docs :)

    Important note RSA is limited for encryption purposes in that you can only encrypt a message that <= key size. That is 117 bytes for 1024 Bit RSA and 245 bytes for 2048 RSA. To encrypt larger messages the accepted way is to encrypt the message using AES or similar then encrypt the AES key with the RSA public key. You will the send the AES ciphertext and also the RSA ciphertext containing the key to decrypt the AES ciphertext.

    What I have written above took days of tinkering and reading. I hope it helps somebody achieve their goal faster than that. :)