Encrypting strings with RSAKey the wrong way


#1

I see a lot of examples for encrypting strings using RSAKey which go something like this:

    String value = "blahblahblahblahalhbla";

    BigInteger bi;
    bi.loadFromMemoryBlock(MemoryBlock(value.getCharPointer(), value.length()));

    // encrypt
    rsaPublicKey->applyToValue(bi);

Correct way should be:

    bi.loadFromMemoryBlock(MemoryBlock(value.getCharPointer(), value.getCharPointer().sizeInBytes()));

and the reason is that String can have Unicode characters in it and length() gives the length in characters, not actual bytes.

If you use length() to construct MemoryBlock you will loose bytes and, later on, decrypted string will be lacking characters at the end, compared to the original.

 


#2

You're absolutely right, but which examples are you talking about?

Actually I'd suggest this as the most readable way to do it:

MemoryBlock m;
m << myString;
bi.loadFromMemoryBlock (m);

..but as an ideal example, it could be preferable to make it explicitly UTF8 as below, because otherwise if people compile with UTF32 strings, then calling getCharPointer will return a UTF32 value and everything will be encoded differently..

bi.loadFromMemoryBlock (MemoryBlock (myString.toRawUTF8(), 
                                     myString.getNumBytesAsUTF8()));

#3

I like the

m << myString

way :) Thanks.

 

As for examples, here are just a few:

http://www.juce.com/comment/305048#comment-305048

http://www.juce.com/forum/topic/encryptxml-decodeencryptedxml-functions-thread-while-back-cause-isvalidstring-assertion

http://www.juce.com/comment/293543#comment-293543

http://www.juce.com/comment/253830#comment-253830

etc. which makes me think that quite a few people are doing what I did (use string.length()) and I thought this post might save some time in trying to figure out why suddenly RSA decoded string is missing characters at the end.