0

The following method does not work. decodedMessage ends up with garbage in it instead of the expected results.

I'm following an example here that supposedly works.

public static void POCSimple()
{
    String secretMessage = "short message";
    PublicKey publicKey = null;
    PrivateKey privateKey = null;
    String encodedMessage = "";
    byte[] encodedBytes = null;
    String decodedMessage ="";
    byte[] decodedBytes = null;


    try
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024);
        KeyPair kp = kpg.genKeyPair();
        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();

        Cipher c1 = Cipher.getInstance("RSA");
        c1.init(Cipher.ENCRYPT_MODE, publicKey);
        encodedBytes = c1.doFinal(secretMessage.getBytes());
        encodedMessage = Base64.encodeToString(encodedBytes, Base64.DEFAULT);

        Cipher c2 = Cipher.getInstance("RSA");
        c2.init(Cipher.DECRYPT_MODE, privateKey);
        decodedBytes = c2.doFinal(encodedBytes);
        decodedMessage = Base64.encodeToString(decodedBytes, Base64.DEFAULT);

        String mystring = "look at results";

    }
    catch (Exception e)
    {
        String status = e.toString();
    }


}

Any help would be most appreciated. Thanks, Dean

Community
  • 1
  • 1
Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • 1
    Code looks okay. Are you sure you are getting garbage? `decodedMessage` should be the Base64-encoded version of the secret message. Do you have an example? – Thilo Oct 26 '15 at 00:08

2 Answers2

1

Of course you are getting garbage, this is your sequence:

Plaintext message -> Encrypt -> Encode -> Encoded message

Encoded message -> Decrypt -> Decode -> GARBAGE

You need to undo the Base64 encoding before you can decrypt the message, you are doing the reverse process in the incorrect order!

Edit

Actually its worse, this is your sequence:

Plaintext message -> Encrypt -> Encode -> Encoded message

Encrypted message -> Decrypt -> Encode -> GARBAGE

Try this:

Cipher c1 = Cipher.getInstance("RSA");
c1.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c1.doFinal(secretMessage.getBytes());
encodedMessage = Base64.encodeToString(encodedBytes, Base64.DEFAULT);

Cipher c2 = Cipher.getInstance("RSA");    
c2.init(Cipher.DECRYPT_MODE, privateKey)      
decodedBytes = Base64.decode(encodedMessage.toByteArray(), Base64.DEFAULT);
decryptedMessage = c2.doFinal(decodedBytes);
Steve
  • 836
  • 1
  • 9
  • 17
  • "You need to undo the Base64 encoding before you can decrypt the message" The code in question is not trying to decrypt the Base64 version. It is working on the encrypted bytes directly. The Base64 values are not used at all, presumably they are for display or debugging. The code should work as presented. – Thilo Oct 26 '15 at 06:07
  • The use of the words "encoded" and "decoded" by the OP is incorrect and now that I reread it closely, I can understand your point. I still don't see what the question is asking though. `encodedMessage` is an RSA encrypted and Base64 encoded String while `decodedMessage` is a Base64 encoded plaintext. Some context on what is trying to be achieved here would help. – Steve Oct 26 '15 at 13:13
1

It turns out that in my original code, decodedBytes contained the properly decrypted bytes. The following command was turning decodedBytes into junk characters ...

decodedMessage = Base64.encodeToString(decodedBytes, Base64.DEFAULT);

I replaced that code with ...

String str = new String(decodedBytes, "UTF-8");

And this solved the problem probably because decodedBytes had never been Base64 encoded in the first place.

I also found that using straight RSA I can only encrypt a maximum of 245 bytes if I use a 2048 bit key. less if I use a 1024 bit key.

If larger strings need to be encrypted using asymmetric Public/Private keys then I need to first encrypt a string using symmetric AES and then encrypt the AES key with the public RSA key and send both the encrypted AES key and the encrypted message over the wire where the receiver can decrypt the AES key using their private RSA key. The AES key can be randomly generated in the sending code.

Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • I would not call Base64 junk, but good to see that you solved the problem and learned something along the way. – Thilo Oct 26 '15 at 23:45