76947

How to encrypt/decrypt long input messages with RSA? [Openssl, C]

Question:

I wrote a simple test program that encrypts/decrypts a message.

I have a keylength:

int keylength = 1024; // it can also be 2048, 4096

and max input length:

int maxlen = (keylength/8)-11;

and I know that my input size should be < than maxlen, something like this:

if(insize >= maxlen) printf("cannot encrypt/decrypt!\n");

My question is simple - is it possible (if so, how can I do this) to encrypt/decrypt with RSA messages LONGER than maxlen?

Main code is also, very simple but works only when insize < maxlen:

if((encBytes=RSA_public_encrypt(strlen(buff1)+1, buff1, buff2, keypair, RSA_PKCS1_PADDING)) == -1) { printf("error\n"); } if((decBytes=RSA_private_decrypt(encBytes, buff2, buff3, keypair, RSA_PKCS1_PADDING)) == -1) { printf("error\n"); }

Answer1:

Encrypting long messages requires combined scheme - RSA algorithm encrypts session key (i.e. AES key), and data itself is encrypted with that key. I would recommend to not invent another bicycle and use well established scheme, i.e. PKCS#7/CMS or OpenPGP, depending on your needs.

Answer2:

You can use RSA as block cipher in that case. That is break the message to several blocks smaller than maxlen. Otherwise impossible.

Answer3:

You would be able to encrypt long messages with <strong>RSA</strong> the same way as it is done with block ciphers. That is, encrypt the messages in blocks and bind the blocks with an appropriate <em>chaining mode</em>. However, this is not the usual way to do it and you won't find support for it (RSA chaining) in the libraries you use.

Since <strong>RSA</strong> is quite slow, the usual way to encrypt large messages is using hybrid encryption. In hybrid encryption you use a fast symmetric encryption algorithm (like <strong>AES</strong>) for encrypting the data with a random key. The random key is then encrypted with <strong>RSA</strong> and send along with the symmetric key encrypted data.

EDIT:

As fore your implementation, you have insize = 1300 and keylength = 1024 which gives maxlen = 117. To encrypt the full message you those needs 12 encrypts, that each produce 128 bytes, giving an encrypted size of 1536 bytes. In your code you only allocates buffers of 1416 bytes. Also, you don't seem to allow for 128 bytes output as you only increment with 117 in:

RSA_public_encrypt(maxlen, buff1+i, buff2+i, keypair, RSA_PKCS1_PADDING)

and

i += maxlen;

Answer4:

If you want to run RSA in a "block cipher" kind of mode, you would need to run it in a loop.

Like most of the other commenters, I'd like to point out that this is a bad use of RSA - You should just encrypt a AES key with RSA then use AES for the longer message.

However, I'm not one to let practicality get in the way of learning, so here's how you'd do it. This code isn't tested, since I don't know what libraries you are using. It's also a little overly-verbose, for readability.

int inLength = strlen(buff1)+1; int numBlocks = (inLength / maxlen) + 1; for (int i = 0; i < numBlocks; i++) { int bytesDone = i * maxlen; int remainingLen = inLength - bytesDone; int thisLen; // The length of this block if (remainingLen > maxlen) { thisLen = maxlen; } else { thisLen = remainingLen; } if((encBytes=RSA_public_encrypt(thisLen, buff1 + bytesDone, buff2 + bytesDone, keypair, RSA_PKCS1_PADDING)) == -1) { printf("error\n"); } // Okay, IDK what the first parameter to this should be. It depends on the library. You can figure it out, hopefully. if((decBytes=RSA_private_decrypt(idk, buff2 + bytesDone, buff3 + bytesDone, keypair, RSA_PKCS1_PADDING)) == -1) { printf("error\n"); } }

Recommend

  • Loading HTML from localStorage breaks function of a button
  • ClassNotFoundException when loading applet on some computers
  • Admob ad Error code : 0. Everithyng is updated and carefully programmed set it's not showing ad
  • Simple PHP mongoDB Username and Password Check for site
  • What's the idiomatic way to pass by mutable value?
  • Select * sql query vs Select specific columns sql query [duplicate]
  • Problems using em units in Chrome
  • php Mail() and Outlook
  • What is causing this error? Error executing child request for handler 'System.Web.Mvc.HttpHandl
  • How can I see the full nodejs “require()” tree starting at a given file?
  • Solr Custom Similarity - Using a field from the indexed document
  • Split dataset based on column values in spark
  • invoking functions while debugging with Visual Studio 2005?
  • How to manipulate context - attach function to context or wrap dispatch in hook?
  • Pinch zoom shifting image to most left corner on iPad in iOS?
  • Call to undefined function Illuminate\\Filesystem\\finfo_file()
  • Android : Databinding, notifyPropertyChanged() not working?
  • How to utilize sizeof() to return the size of malloc buffer allocation [duplicate]
  • Listview MouseDoubleClickEvent create in behind code
  • Numberlink/Flow Game: How to spot NP-Complete problems?
  • Android: Determining the angle of tilt using only accelerometers
  • make meteor restful api/web-service
  • Use CKeditor instance in Vue.js
  • Can't copy sqlite database from assets folder in Android
  • bulk collect …for all usage
  • How to update listview automatically after adding a new item into DB
  • how to print a web page [duplicate]
  • how to make datetime class to work with DST and without DST in php?
  • laravel 5.1 auth csrf token mismatch
  • How to wrap string in span before and after all newlines in PHP?
  • Mocking OpenXML with Moq
  • Select Checkbox !== Select Row Table
  • How to create wsdl from xsd
  • Validating a Firebase Key [duplicate]
  • Jekyll - How do I create pages in the root directory?
  • android : speech recognition what are the technologies available
  • Java Collections.shuffle() weird behaviour [closed]
  • Why does Rails 3 think xE2x80x89 means â x80 x89