Java Encryption: RSA Block Size?

Please support our Java advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster

Java Encryption: RSA Block Size?

 
0
  #1
Oct 18th, 2009
How would one calculate the number of bytes of plaintext that could be encrypted as a single block given the key size? And how could you then calculate the number of bytes of cipher text that can be decrypted in a single block given the same key size because I am told that the two sizes are different.

I tried using
  1. Cipher.getBlockSize()
but that only returns 0. Thanks for your help.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 53
Reputation: neilcoffey will become famous soon enough neilcoffey will become famous soon enough 
Solved Threads: 6
neilcoffey neilcoffey is offline Offline
Junior Poster in Training

Key length - 11 bytes but be careful...!

 
0
  #2
Oct 18th, 2009
Normally, you get the number of bits dictated by the key size (e.g. 512-bit key = 64 bytes) minus a few bytes (11, I think) of overhead. For the gory details, see the so-called PKCS #1 standard: http://tools.ietf.org/html/rfc3447#page-35

However, if you're worrying about this, you may be doing something wrong! RSA isn't really designed to be used as a regular block cipher. The idea is that you use RSA to encrypt the key of some other block cipher, e.g. AES. And usually, the number of bits in the RSA key will be much greater than the number of bits in the AES key or other you're encrypting-- e.g. you might have a 2048-bit RSA key and a 128 or 256-bit AES key.

You might be interested in some stuff I've written about RSA encryption in Java that includes an evaluation of different key lengths.
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster
 
0
  #3
Oct 18th, 2009
It's for an assignment. It's demonstrating that AES, for example, is much better to use than RSA when it comes to encryption. I have to get it to work for both types. I'm not having anywhere near as much trouble with the AES portion.

Overhead is 11 bytes apparently. So does that mean for encryption I use a block size of
  1. int blockSize = KeypairGenerator.getPublicKey().length() - 11; // I know that the .length() portion isn't valid.

If so, how would I calculate the length of the public key?

I have a 2048 bit key. From your original post, it appears that the blocksize for encrypting should be the same as the blocksize for decrypting, but my professor told us this isn't the case.
Last edited by leverin4; Oct 18th, 2009 at 1:31 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 53
Reputation: neilcoffey will become famous soon enough neilcoffey will become famous soon enough 
Solved Threads: 6
neilcoffey neilcoffey is offline Offline
Junior Poster in Training
 
0
  #4
Oct 18th, 2009
Originally Posted by leverin4 View Post
I have a 2048 bit key. From your original post, it appears that the blocksize for encrypting should be the same as the blocksize for decrypting, but my professor told us this isn't the case.
No, not exactly although you're on the right track. If you have a 2048-bit key, then the encrypted data will be an array of 2048/8 = 256 bytes. Then, the input data can be up to 256-11=245 bytes.

One thing to remember is that with RSA and actually many other algorithms including AES usually, the "useful" data that you supply isn't literally the data that's encrypted. Usually, some extra data needs to be included, for example, indicating the actual length of the data in some way, data for any integrity checking... To the user, the number of input bytes doesn't necessarily equal the number of bytes following encryption.
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster
 
0
  #5
Oct 18th, 2009
Originally Posted by neilcoffey View Post
No, not exactly although you're on the right track. If you have a 2048-bit key, then the encrypted data will be an array of 2048/8 = 256 bytes. Then, the input data can be up to 256-11=245 bytes.

One thing to remember is that with RSA and actually many other algorithms including AES usually, the "useful" data that you supply isn't literally the data that's encrypted. Usually, some extra data needs to be included, for example, indicating the actual length of the data in some way, data for any integrity checking... To the user, the number of input bytes doesn't necessarily equal the number of bytes following encryption.
So when reading the plaintext, I should be able to take 245 bytes at a time and encrypt them? But the encryptor will return more than 245 bits, correct?

Then when I get down to the final block, if I'm not using any padding, then I'll have to manually fill in the extra bytes, and remember how many of those I manually filled in, so when I decrypt I remember to not print those out, yes?

But when I encrypt and decrypt, I'm always pulling 245 bytes of either plain text or ciphertext, but the amount I get back is what is different. I hope my rambling makes sense. Can you verify if I'm correct?
Last edited by leverin4; Oct 18th, 2009 at 2:31 pm.
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster
 
0
  #6
Oct 18th, 2009
Actually, it appears that when encrypting, I use a blocksize of (2048 / 8) - 11 , or 245, bytes, and that returns a block of ciphertext consisting of 256 bytes.

When decrypting, I need to pass in a 256-byte block of ciphertext and it should return a 245 byte block of plaintext, correct?
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 53
Reputation: neilcoffey will become famous soon enough neilcoffey will become famous soon enough 
Solved Threads: 6
neilcoffey neilcoffey is offline Offline
Junior Poster in Training
 
0
  #7
Oct 18th, 2009
Originally Posted by leverin4 View Post
Actually, it appears that when encrypting, I use a blocksize of (2048 / 8) - 11 , or 245, bytes, and that returns a block of ciphertext consisting of 256 bytes.
Yes.

Originally Posted by leverin4 View Post
When decrypting, I need to pass in a 256-byte block of ciphertext and it should return a 245 byte block of plaintext, correct?
Not necessarily. It returns a byte array containing the original data. So if you encrypt 1 byte, you'll get 256 bytes of ciphertext (with a 2048-bit key). Then, when you decrypt those 256 bytes of ciphertext, you'll get a 1-byte array containing the original single byte you encrypted.

The actual number of bytes of original plaintext is "magically" encoded during encyption (that's partly why you loose 11 bytes-- to encode the length plus an integrity check).
Last edited by neilcoffey; Oct 18th, 2009 at 4:32 pm.
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster
 
0
  #8
Oct 18th, 2009
So does this mean I don't have to manually pad anything? See code below for clarification.

  1. DataInputStream pInRSA = new DataInputStream(new FileInputStream(inFile));
  2. DataOutputStream eOutRSA = new DataOutputStream(new FileOutputStream("RSACipherText.txt"));
  3. encoderRSA = Cipher.getInstance("RSA/ECB/NoPadding");
  4. encoderRSA.init(Cipher.ENCRYPT_MODE, keyRSA.getPublic());
  5. blockSize = (2048 / 8) - 11;
  6. buffer = new byte[blockSize];
  7. count = 0;
  8.  
  9. while (pInRSA.available() > 0) {
  10. int i = 0;
  11. if (pInRSA.available() > blockSize) {
  12. while (i < blockSize) {
  13. buffer[i] = pInRSA.readByte();
  14. count++;
  15. i++;
  16. }
  17. } else {
  18. while (pInRSA.available() > 0) {
  19. buffer[i] = pInRSA.readByte();
  20. count++;
  21. i++;
  22. }
  23. while (i < blockSize) {
  24. buffer[i] = Byte.MAX_VALUE;
  25. i++;
  26. }
  27. }
  28. encodedMsg = encoderRSA.doFinal(buffer);
  29. eOutRSA.write(encodedMsg, 0, encodedMsg.length);
  30. }
  31. pInRSA.close();
  32. eOutRSA.close();

Basically what you're telling me is that my else block in the code is pointless?
Last edited by leverin4; Oct 18th, 2009 at 4:41 pm.
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 49
Reputation: leverin4 is an unknown quantity at this point 
Solved Threads: 3
leverin4 leverin4 is offline Offline
Light Poster
 
0
  #9
Oct 18th, 2009
I could do something like
  1. DataInputStream pInRSA = new DataInputStream(new FileInputStream(inFile));
  2. DataOutputStream eOutRSA = new DataOutputStream(new FileOutputStream("RSACipherText.txt"));
  3. encoderRSA = Cipher.getInstance("RSA/ECB/NoPadding");
  4. encoderRSA.init(Cipher.ENCRYPT_MODE, keyRSA.getPublic());
  5. blockSize = (2048 / 8) - 11;
  6. count = 0;
  7.  
  8. while (pInRSA.available() > 0) {
  9. buffer = new byte[Math.min(blockSize, pInRSA.available())];
  10. for (int i = 0; i < buffer.length; i++) {
  11. buffer[i] = pInRSA.readByte();
  12. count++;
  13. }
  14. encodedMsg = encoderRSA.doFinal(buffer);
  15. eOutRSA.write(encodedMsg, 0, encodedMsg.length);
  16. }
  17. pInRSA.close();
  18. eOutRSA.close();
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 53
Reputation: neilcoffey will become famous soon enough neilcoffey will become famous soon enough 
Solved Threads: 6
neilcoffey neilcoffey is offline Offline
Junior Poster in Training
 
0
  #10
Oct 18th, 2009
You must use padding, but unless you're really sure of what you're doing, it's best to let the library do it. So just instantiate your Cipher as "RSA"-- don't specify Nopadding!
Reply With Quote Quick reply to this message  
Reply

Tags
block, encryption, java, rsa, size

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC